Stabilize `Result::as_deref` and `as_deref_mut`
FCP completed in https://github.com/rust-lang/rust/issues/50264#issuecomment-645681400.
This PR stabilizes two new APIs for `std::result::Result`:
```rust
fn as_deref(&self) -> Result<&T::Target, &E> where T: Deref;
fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> where T: DerefMut;
```
This PR also removes two rarely used unstable APIs from `Result`:
```rust
fn as_deref_err(&self) -> Result<&T, &E::Target> where E: Deref;
fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> where E: DerefMut;
```
Closes#50264
compiletest: Support ignoring tests requiring missing LLVM components
This PR implements a more principled solution to the problem described in https://github.com/rust-lang/rust/pull/66084.
Builds of LLVM backends take a lot of time and disk space.
So it usually makes sense to build rustc with
```toml
[llvm]
targets = "X86"
experimental-targets = ""
```
unless you are working on some target-specific tasks.
A few tests, however, require non-x86 backends to be built.
A new test directive `// needs-llvm-components: component1 component2 component3` makes such tests to be automatically ignored if one of the listed components is missing in the provided LLVM (this is determined through `llvm-config --components`).
As a result, the test suite now fully passes with LLVM built only with the x86 backend. The component list in this case is
```
aggressiveinstcombine all all-targets analysis asmparser asmprinter binaryformat bitreader bitstreamreader bitwriter cfguard codegen core coroutines coverage debuginfocodeview debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker engine executionengine frontendopenmp fuzzmutate globalisel instcombine instrumentation interpreter ipo irreader jitlink libdriver lineeditor linker lto mc mca mcdisassembler mcjit mcparser mirparser native nativecodegen objcarcopts object objectyaml option orcerror orcjit passes profiledata remarks runtimedyld scalaropts selectiondag support symbolize tablegen target textapi transformutils vectorize windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86utils xray
```
(With the default target list it's much larger.)
```
aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter cfguard codegen core coroutines coverage debuginfocodeview debuginfodwarf debuginfogsym debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker engine executionengine frontendopenmp fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interpreter ipo irreader jitlink libdriver lineeditor linker lto mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts object objectyaml option orcerror orcjit passes powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvutils runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target textapi transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86utils xray
```
https://github.com/rust-lang/rust/pull/66084 is also reverted now.
r? @Mark-Simulacrum
Fix ICEs with `@ ..` binding
This reverts #74557 and introduces an alternative fix while ensuring that #74954 is not broken.
The diagnostics are verbose though, it fixes three related issues.
cc #74954, #74539, and #74702
Deduplicate `::` -> `:` typo errors
Deduplicate errors caused by the same type ascription typo, including
ones suggested during parsing that would get reported again during
resolve. Fix#70382.
[mir] Special treatment for dereferencing a borrow to a static definition
Fix#70584.
As suggested by @oli-obk in this [comment](https://github.com/rust-lang/rust/issues/70584#issuecomment-626009260), one can chase the definition of the local variable being de-referenced and check if it is a true static variable. If that is the case, `validate_place` will admit the promotion.
This is my first time to contribute to `rustc`, and I have two questions.
1. A generalization to some extent is applied to decide if the promotion is possible in the static context. In case that there are more projection operations preceding the de-referencing, `validate_place` recursively decent into inner projection operations. I have put thoughts into its correctness but I am not totally sure about it.
2. I have a hard time to find a good place for the test case. This patch has to do with MIR, but this test case would look out of place compared to other tests in `src/test/ui/mir` or `src/test/ui/borrowck` because it does not generate errors while others do. It is tentatively placed in `src/test/ui/statics` for now.
Thank you for any comments and suggestions!
mir: add `used_generic_parameters_needs_subst`
Fixes#74636.
This PR adds a `used_generic_parameters_needs_subst` helper function which checks whether a type needs substitution, but only for parameters that the `unused_generic_params` query considers used. This is used in the MIR interpreter to make the check for some pointer casts and for reflection intrinsics more precise.
I've opened this as a draft PR because this might not be the approach we want to fix this issue and we have to decide what to do about the reflection case.
r? @eddyb
cc @lcnr @wesleywiser
Fix Const-Generic Cycle ICE #74199
This PR intends to fix the bug in Issue #74199 by following the suggestion provided of ignoring the error that causes the ICE.
This does not fix the underlying cycle detection issue, but fixes the ICE.
Also adds a test to check that it doesn't causes an ICE but returns a valid error for now.
r? @lcnr
Edit: Also it's funny how this PR number is an anagram of the issue number
* Deduplicate type ascription LHS errors
* Remove duplicated `:` -> `::` suggestion from parse error
* Tweak wording to be more accurate
* Modify `current_type_ascription` to reduce span wrangling
* remove now unnecessary match arm
* Add run-rustfix to appropriate tests
This commit adds a `ensure_monomorphic_enough` utility function which
checks whether a type needs substitution, but only for parameters
that the `unused_generic_params` query considers used.
`ensure_monomorphic_enough` is then used throughout interpret where
`needs_subst` checks previously existed (in particular, for some
pointer casts and for reflection intrinsics more precise).
Signed-off-by: David Wood <david@davidtw.co>
Make `Option::unwrap` unstably const
This is lumped into the `const_option` feature gate (#67441), which enables a potpourri of `Option` methods.
cc @rust-lang/wg-const-eval
r? @oli-obk
Improve diagnostics when constant pattern is too generic
This PR is a follow-up to PR #74538 and issue #73976
When constants queries Layout, TypeId or type_name of a generic parameter, instead of emitting `could not evaluate constant pattern`, we will instead emit a more detailed message `constant pattern depends on a generic parameter`.
Fix incorrect clashing_extern_declarations warnings.
Fixes#73735, fixes#73872.
Fix clashing_extern_declarations warning for `#[repr(transparent)]` structs and safely-FFI-convertible enums, and not warning for clashes of struct members of different types, but the same size.
r? @nagisa
Make `mem::size_of_val` and `mem::align_of_val` unstably const
Implements #46571 but does not stabilize it. I wanted this while working on something today.
The only reason not to immediately stabilize are concerns around [custom DSTs](https://github.com/rust-lang/rust/issues/46571#issuecomment-387669352). That proposal has made zero progress in the last two years and const eval is rich enough to support pretty much any user-defined `len` function as long as nightly features are allowed (`raw_ptr_deref`).
Currently, this raises a `const_err` lint when passed an `extern type`.
r? @oli-obk
cc @rust-lang/wg-const-eval
- Make `is_repr_nullable_ptr` freestanding again to avoid usage of
ImproperCTypesVisitor in ClashingExternDeclarations (and don't
accidentally revert the ParamEnv::reveal_all() fix from a week earlier)
- Revise match condition for 1 Adt, 1 primitive
- Generalise check for non-null type so that it would also work for
ranges which exclude any single value (all bits set, for example)
- Make is_repr_nullable_ptr return the representable type instead of
just a boolean, to avoid adding an additional, independent "source of
truth" about the FFI-compatibility of Option-like enums. Also, rename to
`repr_nullable_ptr`.
An example of an FFI-safe enum conversion is when converting
Option<NonZeroUsize> to usize. Because the Some value must be non-zero,
rustc can use 0 to represent the None variant, making this conversion is
safe. Furthermore, it can be relied on (and removing this optimisation
already would be a breaking change).
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.
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.
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:
|| {};
}
```