Auto merge of #131724 - matthiaskrgr:rollup-ntgkkk8, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #130608 (Implemented `FromStr` for `CString` and `TryFrom<CString>` for `String`) - #130635 (Add `&pin (mut|const) T` type position sugar) - #130747 (improve error messages for `C-cmse-nonsecure-entry` functions) - #131137 (Add 1.82 release notes) - #131328 (Remove unnecessary sorts in `rustc_hir_analysis`) - #131496 (Stabilise `const_make_ascii`.) - #131706 (Fix two const-hacks) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
88f311479d
50 changed files with 1126 additions and 185 deletions
177
RELEASES.md
177
RELEASES.md
|
@ -1,3 +1,180 @@
|
||||||
|
Version 1.82.0 (2024-10-17)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
<a id="1.82.0-Language"></a>
|
||||||
|
|
||||||
|
Language
|
||||||
|
--------
|
||||||
|
- [Don't make statement nonterminals match pattern nonterminals](https://github.com/rust-lang/rust/pull/120221/)
|
||||||
|
- [Patterns matching empty types can now be omitted in common cases](https://github.com/rust-lang/rust/pull/122792)
|
||||||
|
- [Enforce supertrait outlives obligations when using trait impls](https://github.com/rust-lang/rust/pull/124336)
|
||||||
|
- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834)
|
||||||
|
- [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/)
|
||||||
|
- [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/)
|
||||||
|
- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
|
||||||
|
- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679)
|
||||||
|
- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921)
|
||||||
|
- [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284)
|
||||||
|
- [Do not require `T` to be live when dropping `[T; 0]`](https://github.com/rust-lang/rust/pull/128438)
|
||||||
|
- [Stabilize `const` operands in inline assembly](https://github.com/rust-lang/rust/pull/128570)
|
||||||
|
- [Stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596)
|
||||||
|
- [Stabilize explicit opt-in to unsafe attributes](https://github.com/rust-lang/rust/pull/128771)
|
||||||
|
- [Document NaN bit patterns guarantees](https://github.com/rust-lang/rust/pull/129559)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="1.82.0-Compiler"></a>
|
||||||
|
|
||||||
|
Compiler
|
||||||
|
--------
|
||||||
|
- [Promote riscv64gc-unknown-linux-musl to tier 2](https://github.com/rust-lang/rust/pull/122049)
|
||||||
|
- [Promote Mac Catalyst targets `aarch64-apple-ios-macabi` and `x86_64-apple-ios-macabi` to Tier 2, and ship them with rustup](https://github.com/rust-lang/rust/pull/126450)
|
||||||
|
- [Add tier 3 NuttX based targets for RISC-V and ARM](https://github.com/rust-lang/rust/pull/127755)
|
||||||
|
- [Add tier 3 powerpc-unknown-linux-muslspe target](https://github.com/rust-lang/rust/pull/127905)
|
||||||
|
- [Improved diagnostics to explain why a pattern is unreachable](https://github.com/rust-lang/rust/pull/128034)
|
||||||
|
- [The compiler now triggers the unreachable code warning properly for async functions that don't return/are `-> !`](https://github.com/rust-lang/rust/pull/128443)
|
||||||
|
- [Promote `aarch64-apple-darwin` to Tier 1](https://github.com/rust-lang/rust/pull/128592)
|
||||||
|
- [Add Trusty OS target `aarch64-unknown-trusty` and `armv7-unknown-trusty` as tier 3 targets](https://github.com/rust-lang/rust/pull/129490)
|
||||||
|
- [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="1.82.0-Libraries"></a>
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
- [Generalize `{Rc,Arc}::make_mut()` to `Path`, `OsStr`, and `CStr`.](https://github.com/rust-lang/rust/pull/126877)
|
||||||
|
|
||||||
|
<a id="1.82.0-Stabilized-APIs"></a>
|
||||||
|
|
||||||
|
Stabilized APIs
|
||||||
|
---------------
|
||||||
|
|
||||||
|
- [`std::thread::Builder::spawn_unchecked`](https://doc.rust-lang.org/stable/std/thread/struct.Builder.html#method.spawn_unchecked)
|
||||||
|
- [`std::str::CharIndices::offset`](https://doc.rust-lang.org/nightly/std/str/struct.CharIndices.html#method.offset)
|
||||||
|
- [`std::option::Option::is_none_or`](https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.is_none_or)
|
||||||
|
- [`[T]::is_sorted`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted)
|
||||||
|
- [`[T]::is_sorted_by`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by)
|
||||||
|
- [`[T]::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by_key)
|
||||||
|
- [`Iterator::is_sorted`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted)
|
||||||
|
- [`Iterator::is_sorted_by`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by)
|
||||||
|
- [`Iterator::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by_key)
|
||||||
|
- [`std::future::Ready::into_inner`](https://doc.rust-lang.org/nightly/std/future/struct.Ready.html#method.into_inner)
|
||||||
|
- [`std::iter::repeat_n`](https://doc.rust-lang.org/nightly/std/iter/fn.repeat_n.html)
|
||||||
|
- [`impl<T: Clone> DoubleEndedIterator for Take<Repeat<T>>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-DoubleEndedIterator-for-Take%3CRepeat%3CT%3E%3E)
|
||||||
|
- [`impl<T: Clone> ExactSizeIterator for Take<Repeat<T>>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeat%3CT%3E%3E)
|
||||||
|
- [`impl<T: Clone> ExactSizeIterator for Take<RepeatWith<T>>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeatWith%3CF%3E%3E)
|
||||||
|
- [`impl Default for std::collections::binary_heap::Iter`](https://doc.rust-lang.org/nightly/std/collections/binary_heap/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E)
|
||||||
|
- [`impl Default for std::collections::btree_map::RangeMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.RangeMut.html#impl-Default-for-RangeMut%3C'_,+K,+V%3E)
|
||||||
|
- [`impl Default for std::collections::btree_map::ValuesMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.ValuesMut.html#impl-Default-for-ValuesMut%3C'_,+K,+V%3E)
|
||||||
|
- [`impl Default for std::collections::vec_deque::Iter`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E)
|
||||||
|
- [`impl Default for std::collections::vec_deque::IterMut`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.IterMut.html#impl-Default-for-IterMut%3C'_,+T%3E)
|
||||||
|
- [`Rc<T>::new_uninit`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit)
|
||||||
|
- [`Rc<T>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init)
|
||||||
|
- [`Rc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit_slice)
|
||||||
|
- [`Rc<[MaybeUninit<T>]>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init-1)
|
||||||
|
- [`Arc<T>::new_uninit`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit)
|
||||||
|
- [`Arc<T>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init)
|
||||||
|
- [`Arc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit_slice)
|
||||||
|
- [`Arc<[MaybeUninit<T>]>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init-1)
|
||||||
|
- [`Box<T>::new_uninit`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit)
|
||||||
|
- [`Box<T>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init)
|
||||||
|
- [`Box<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit_slice)
|
||||||
|
- [`Box<[MaybeUninit<T>]>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init-1)
|
||||||
|
- [`core::arch::x86_64::_bextri_u64`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u64.html)
|
||||||
|
- [`core::arch::x86_64::_bextri_u32`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u32.html)
|
||||||
|
- [`core::arch::x86::_mm_broadcastsi128_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_broadcastsi128_si256.html)
|
||||||
|
- [`core::arch::x86::_mm256_stream_load_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm256_stream_load_si256.html)
|
||||||
|
- [`core::arch::x86::_tzcnt_u16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._tzcnt_u16.html)
|
||||||
|
- [`core::arch::x86::_mm_extracti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_extracti_si64.html)
|
||||||
|
- [`core::arch::x86::_mm_inserti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_inserti_si64.html)
|
||||||
|
- [`core::arch::x86::_mm_storeu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si16.html)
|
||||||
|
- [`core::arch::x86::_mm_storeu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si32.html)
|
||||||
|
- [`core::arch::x86::_mm_storeu_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si64.html)
|
||||||
|
- [`core::arch::x86::_mm_loadu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si16.html)
|
||||||
|
- [`core::arch::x86::_mm_loadu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si32.html)
|
||||||
|
- [`core::arch::wasm32::u8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_swizzle.html)
|
||||||
|
- [`core::arch::wasm32::i8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_swizzle.html)
|
||||||
|
- [`core::arch::wasm32::i32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f32x4.html)
|
||||||
|
- [`core::arch::wasm32::u32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f32x4.html)
|
||||||
|
- [`core::arch::wasm32::i32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f64x2_zero.html)
|
||||||
|
- [`core::arch::wasm32::u32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f64x2_zero.html)
|
||||||
|
- [`core::arch::wasm32::f32x4_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_madd.html)
|
||||||
|
- [`core::arch::wasm32::f32x4_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_nmadd.html)
|
||||||
|
- [`core::arch::wasm32::f64x2_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_madd.html)
|
||||||
|
- [`core::arch::wasm32::f64x2_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_nmadd.html)
|
||||||
|
- [`core::arch::wasm32::i8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::u8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::i16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::u16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::i32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::u32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::i64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i64x2_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::u64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u64x2_relaxed_laneselect.html)
|
||||||
|
- [`core::arch::wasm32::f32x4_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_min.html)
|
||||||
|
- [`core::arch::wasm32::f32x4_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_max.html)
|
||||||
|
- [`core::arch::wasm32::f64x2_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_min.html)
|
||||||
|
- [`core::arch::wasm32::f64x2_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_max.html)
|
||||||
|
- [`core::arch::wasm32::i16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_q15mulr.html)
|
||||||
|
- [`core::arch::wasm32::u16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_q15mulr.html)
|
||||||
|
- [`core::arch::wasm32::i16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_dot_i8x16_i7x16.html)
|
||||||
|
- [`core::arch::wasm32::u16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_dot_i8x16_i7x16.html)
|
||||||
|
- [`core::arch::wasm32::i32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_dot_i8x16_i7x16_add.html)
|
||||||
|
- [`core::arch::wasm32::u32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_dot_i8x16_i7x16_add.html)
|
||||||
|
|
||||||
|
These APIs are now stable in const contexts:
|
||||||
|
|
||||||
|
- [`std::task::Waker::from_raw`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw)
|
||||||
|
- [`std::task::Waker::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw)
|
||||||
|
- [`std::task::Context::from_waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.from_waker)
|
||||||
|
- [`std::task::Context::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.waker)
|
||||||
|
- [`$integer::from_str_radix`](https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.from_str_radix)
|
||||||
|
- [`std::num::ParseIntError::kind`](https://doc.rust-lang.org/nightly/std/num/struct.ParseIntError.html#method.kind)
|
||||||
|
|
||||||
|
<a id="1.82.0-Cargo"></a>
|
||||||
|
|
||||||
|
Cargo
|
||||||
|
-----
|
||||||
|
- [feat: Add `info` cargo subcommand](https://github.com/rust-lang/cargo/pull/14141/)
|
||||||
|
|
||||||
|
<a id="1.82.0-Compatibility-Notes"></a>
|
||||||
|
|
||||||
|
Compatibility Notes
|
||||||
|
-------------------
|
||||||
|
- We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead.
|
||||||
|
- The standard library has a new implementation of `binary_search` which is significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation.
|
||||||
|
- [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets.
|
||||||
|
- [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400)
|
||||||
|
- The WebAssembly target features `multivalue` and `reference-types` are now
|
||||||
|
both enabled by default. These two features both have subtle changes implied
|
||||||
|
for generated WebAssembly binaries. For the `multivalue` feature, WebAssembly
|
||||||
|
target support has changed when upgrading to LLVM 19. Support for generating
|
||||||
|
functions with multiple returns no longer works and
|
||||||
|
`-Ctarget-feature=+multivalue` has a different meaning than it did in LLVM 18
|
||||||
|
and prior. There is no longer any supported means to generate a module that has
|
||||||
|
a function with multiple returns in WebAssembly from Rust source code. For the
|
||||||
|
`reference-types` feature the encoding of immediates in the `call_indirect`, a
|
||||||
|
commonly used instruction by the WebAssembly backend, has changed. Validators
|
||||||
|
and parsers which don't understand the `reference-types` proposal will no
|
||||||
|
longer accept modules produced by LLVM due to this change in encoding of
|
||||||
|
immediates. Additionally these features being enabled are encoded in the
|
||||||
|
`target_features` custom section and may affect downstream tooling such as
|
||||||
|
`wasm-opt` consuming the module. Generating a WebAssembly module that disables
|
||||||
|
default features requires `-Zbuild-std` support from Cargo and more information
|
||||||
|
can be found at
|
||||||
|
[rust-lang/rust#128511](https://github.com/rust-lang/rust/pull/128511).
|
||||||
|
- [Rust now raises unsafety errors for union patterns in parameter-position](https://github.com/rust-lang/rust/pull/130531)
|
||||||
|
|
||||||
|
|
||||||
|
<a id="1.82.0-Internal-Changes"></a>
|
||||||
|
|
||||||
|
Internal Changes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
These changes do not affect any public interfaces of Rust, but they represent
|
||||||
|
significant improvements to the performance or internals of rustc and related
|
||||||
|
tools.
|
||||||
|
|
||||||
|
- [Update to LLVM 19](https://github.com/rust-lang/rust/pull/127513)
|
||||||
|
|
||||||
Version 1.81.0 (2024-09-05)
|
Version 1.81.0 (2024-09-05)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ use std::{cmp, fmt, mem};
|
||||||
|
|
||||||
pub use GenericArgs::*;
|
pub use GenericArgs::*;
|
||||||
pub use UnsafeSource::*;
|
pub use UnsafeSource::*;
|
||||||
pub use rustc_ast_ir::{Movability, Mutability};
|
pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
|
||||||
use rustc_data_structures::packed::Pu128;
|
use rustc_data_structures::packed::Pu128;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
|
@ -2161,6 +2161,10 @@ pub enum TyKind {
|
||||||
Ptr(MutTy),
|
Ptr(MutTy),
|
||||||
/// A reference (`&'a T` or `&'a mut T`).
|
/// A reference (`&'a T` or `&'a mut T`).
|
||||||
Ref(Option<Lifetime>, MutTy),
|
Ref(Option<Lifetime>, MutTy),
|
||||||
|
/// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
|
||||||
|
///
|
||||||
|
/// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
|
||||||
|
PinnedRef(Option<Lifetime>, MutTy),
|
||||||
/// A bare function (e.g., `fn(usize) -> bool`).
|
/// A bare function (e.g., `fn(usize) -> bool`).
|
||||||
BareFn(P<BareFnTy>),
|
BareFn(P<BareFnTy>),
|
||||||
/// The never type (`!`).
|
/// The never type (`!`).
|
||||||
|
@ -2501,7 +2505,10 @@ impl Param {
|
||||||
if ident.name == kw::SelfLower {
|
if ident.name == kw::SelfLower {
|
||||||
return match self.ty.kind {
|
return match self.ty.kind {
|
||||||
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
|
||||||
TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
|
TyKind::Ref(lt, MutTy { ref ty, mutbl })
|
||||||
|
| TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
|
||||||
|
if ty.kind.is_implicit_self() =>
|
||||||
|
{
|
||||||
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
|
||||||
}
|
}
|
||||||
_ => Some(respan(
|
_ => Some(respan(
|
||||||
|
|
|
@ -485,7 +485,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
}
|
}
|
||||||
TyKind::Slice(ty) => vis.visit_ty(ty),
|
TyKind::Slice(ty) => vis.visit_ty(ty),
|
||||||
TyKind::Ptr(mt) => vis.visit_mt(mt),
|
TyKind::Ptr(mt) => vis.visit_mt(mt),
|
||||||
TyKind::Ref(lt, mt) => {
|
TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => {
|
||||||
visit_opt(lt, |lt| vis.visit_lifetime(lt));
|
visit_opt(lt, |lt| vis.visit_lifetime(lt));
|
||||||
vis.visit_mt(mt);
|
vis.visit_mt(mt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,9 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
|
||||||
break (mac.args.delim == Delimiter::Brace).then_some(mac);
|
break (mac.args.delim == Delimiter::Brace).then_some(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::TyKind::Ptr(mut_ty) | ast::TyKind::Ref(_, mut_ty) => {
|
ast::TyKind::Ptr(mut_ty)
|
||||||
|
| ast::TyKind::Ref(_, mut_ty)
|
||||||
|
| ast::TyKind::PinnedRef(_, mut_ty) => {
|
||||||
ty = &mut_ty.ty;
|
ty = &mut_ty.ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -499,7 +499,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
match kind {
|
match kind {
|
||||||
TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)),
|
TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)),
|
||||||
TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)),
|
TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)),
|
||||||
TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) => {
|
TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ })
|
||||||
|
| TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => {
|
||||||
visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
|
visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref);
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,3 +79,10 @@ impl Mutability {
|
||||||
matches!(self, Self::Not)
|
matches!(self, Self::Not)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||||
|
pub enum Pinnedness {
|
||||||
|
Not,
|
||||||
|
Pinned,
|
||||||
|
}
|
||||||
|
|
|
@ -640,7 +640,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.lower_span(span),
|
self.lower_span(span),
|
||||||
Some(self.allow_gen_future.clone()),
|
Some(self.allow_gen_future.clone()),
|
||||||
);
|
);
|
||||||
let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span);
|
let resume_ty =
|
||||||
|
self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None);
|
||||||
let input_ty = hir::Ty {
|
let input_ty = hir::Ty {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
kind: hir::TyKind::Path(resume_ty),
|
kind: hir::TyKind::Path(resume_ty),
|
||||||
|
@ -2065,7 +2066,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span));
|
let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span), None);
|
||||||
let path = hir::ExprKind::Path(hir::QPath::TypeRelative(
|
let path = hir::ExprKind::Path(hir::QPath::TypeRelative(
|
||||||
self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))),
|
self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))),
|
||||||
self.arena.alloc(hir::PathSegment::new(
|
self.arena.alloc(hir::PathSegment::new(
|
||||||
|
|
|
@ -55,8 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey};
|
||||||
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
||||||
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
|
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName,
|
self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, MissingLifetimeKind,
|
||||||
TraitCandidate,
|
ParamName, TraitCandidate,
|
||||||
};
|
};
|
||||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
|
@ -765,8 +765,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> {
|
fn make_lang_item_qpath(
|
||||||
hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, None))
|
&mut self,
|
||||||
|
lang_item: hir::LangItem,
|
||||||
|
span: Span,
|
||||||
|
args: Option<&'hir hir::GenericArgs<'hir>>,
|
||||||
|
) -> hir::QPath<'hir> {
|
||||||
|
hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_lang_item_path(
|
fn make_lang_item_path(
|
||||||
|
@ -1277,6 +1282,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let lifetime = self.lower_lifetime(®ion);
|
let lifetime = self.lower_lifetime(®ion);
|
||||||
hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
|
hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))
|
||||||
}
|
}
|
||||||
|
TyKind::PinnedRef(region, mt) => {
|
||||||
|
let region = region.unwrap_or_else(|| {
|
||||||
|
let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
|
||||||
|
self.resolver.get_lifetime_res(t.id)
|
||||||
|
{
|
||||||
|
debug_assert_eq!(start.plus(1), end);
|
||||||
|
start
|
||||||
|
} else {
|
||||||
|
self.next_node_id()
|
||||||
|
};
|
||||||
|
let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
|
||||||
|
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
|
||||||
|
});
|
||||||
|
let lifetime = self.lower_lifetime(®ion);
|
||||||
|
let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));
|
||||||
|
let span = self.lower_span(t.span);
|
||||||
|
let arg = hir::Ty { kind, span, hir_id: self.next_id() };
|
||||||
|
let args = self.arena.alloc(hir::GenericArgs {
|
||||||
|
args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),
|
||||||
|
constraints: &[],
|
||||||
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
|
span_ext: span,
|
||||||
|
});
|
||||||
|
let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
|
||||||
|
hir::TyKind::Path(path)
|
||||||
|
}
|
||||||
TyKind::BareFn(f) => {
|
TyKind::BareFn(f) => {
|
||||||
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
|
let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);
|
||||||
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
|
hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy {
|
||||||
|
@ -1845,10 +1876,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Given we are only considering `ImplicitSelf` types, we needn't consider
|
// Given we are only considering `ImplicitSelf` types, we needn't consider
|
||||||
// the case where we have a mutable pattern to a reference as that would
|
// the case where we have a mutable pattern to a reference as that would
|
||||||
// no longer be an `ImplicitSelf`.
|
// no longer be an `ImplicitSelf`.
|
||||||
TyKind::Ref(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl {
|
TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)
|
||||||
hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
|
if mt.ty.kind.is_implicit_self() =>
|
||||||
hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
|
{
|
||||||
},
|
match mt.mutbl {
|
||||||
|
hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,
|
||||||
|
hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => hir::ImplicitSelfKind::None,
|
_ => hir::ImplicitSelfKind::None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> {
|
||||||
visit::walk_ty(self, t);
|
visit::walk_ty(self, t);
|
||||||
self.current_binders.pop();
|
self.current_binders.pop();
|
||||||
}
|
}
|
||||||
TyKind::Ref(None, _) => {
|
TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {
|
||||||
self.record_elided_anchor(t.id, t.span);
|
self.record_elided_anchor(t.id, t.span);
|
||||||
visit::walk_ty(self, t);
|
visit::walk_ty(self, t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,6 +546,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||||
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
|
||||||
gate_all!(global_registration, "global registration is experimental");
|
gate_all!(global_registration, "global registration is experimental");
|
||||||
gate_all!(return_type_notation, "return type notation is experimental");
|
gate_all!(return_type_notation, "return type notation is experimental");
|
||||||
|
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
|
||||||
|
|
||||||
if !visitor.features.never_patterns {
|
if !visitor.features.never_patterns {
|
||||||
if let Some(spans) = spans.get(&sym::never_patterns) {
|
if let Some(spans) = spans.get(&sym::never_patterns) {
|
||||||
|
|
|
@ -1163,6 +1163,12 @@ impl<'a> State<'a> {
|
||||||
self.print_opt_lifetime(lifetime);
|
self.print_opt_lifetime(lifetime);
|
||||||
self.print_mt(mt, false);
|
self.print_mt(mt, false);
|
||||||
}
|
}
|
||||||
|
ast::TyKind::PinnedRef(lifetime, mt) => {
|
||||||
|
self.word("&");
|
||||||
|
self.print_opt_lifetime(lifetime);
|
||||||
|
self.word("pin ");
|
||||||
|
self.print_mt(mt, true);
|
||||||
|
}
|
||||||
ast::TyKind::Never => {
|
ast::TyKind::Never => {
|
||||||
self.word("!");
|
self.word("!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_ast as ast;
|
|
||||||
use rustc_ast::util::parser::ExprPrecedence;
|
use rustc_ast::util::parser::ExprPrecedence;
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind,
|
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
|
||||||
TraitObjectSyntax, UintTy,
|
LitKind, TraitObjectSyntax, UintTy,
|
||||||
};
|
};
|
||||||
pub use rustc_ast::{
|
pub use rustc_ast::{
|
||||||
BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy, ImplPolarity, IsAuto, Movability,
|
BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy, ImplPolarity, IsAuto, Movability,
|
||||||
|
|
|
@ -68,18 +68,21 @@ hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are fo
|
||||||
hir_analysis_cmse_call_generic =
|
hir_analysis_cmse_call_generic =
|
||||||
function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type
|
function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type
|
||||||
|
|
||||||
hir_analysis_cmse_call_inputs_stack_spill =
|
hir_analysis_cmse_entry_generic =
|
||||||
arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers
|
functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
|
||||||
|
hir_analysis_cmse_inputs_stack_spill =
|
||||||
|
arguments for `"{$abi_name}"` function too large to pass via registers
|
||||||
.label = {$plural ->
|
.label = {$plural ->
|
||||||
[false] this argument doesn't
|
[false] this argument doesn't
|
||||||
*[true] these arguments don't
|
*[true] these arguments don't
|
||||||
} fit in the available registers
|
} fit in the available registers
|
||||||
.note = functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
.note = functions with the `"{$abi_name}"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
hir_analysis_cmse_call_output_stack_spill =
|
hir_analysis_cmse_output_stack_spill =
|
||||||
return value of `"C-cmse-nonsecure-call"` function too large to pass via registers
|
return value of `"{$abi_name}"` function too large to pass via registers
|
||||||
.label = this type doesn't fit in the available registers
|
.label = this type doesn't fit in the available registers
|
||||||
.note1 = functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
|
.note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
|
||||||
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
|
||||||
|
|
|
@ -531,7 +531,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
||||||
debug!(?required_bounds);
|
debug!(?required_bounds);
|
||||||
let param_env = tcx.param_env(gat_def_id);
|
let param_env = tcx.param_env(gat_def_id);
|
||||||
|
|
||||||
let mut unsatisfied_bounds: Vec<_> = required_bounds
|
let unsatisfied_bounds: Vec<_> = required_bounds
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|clause| match clause.kind().skip_binder() {
|
.filter(|clause| match clause.kind().skip_binder() {
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
|
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {
|
||||||
|
@ -552,9 +552,6 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
||||||
.map(|clause| clause.to_string())
|
.map(|clause| clause.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// We sort so that order is predictable
|
|
||||||
unsatisfied_bounds.sort();
|
|
||||||
|
|
||||||
if !unsatisfied_bounds.is_empty() {
|
if !unsatisfied_bounds.is_empty() {
|
||||||
let plural = pluralize!(unsatisfied_bounds.len());
|
let plural = pluralize!(unsatisfied_bounds.len());
|
||||||
let suggestion = format!(
|
let suggestion = format!(
|
||||||
|
|
|
@ -319,9 +319,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||||
// List of connected regions is built. Now, run the overlap check
|
// List of connected regions is built. Now, run the overlap check
|
||||||
// for each pair of impl blocks in the same connected region.
|
// for each pair of impl blocks in the same connected region.
|
||||||
for region in connected_regions.into_iter().flatten() {
|
for region in connected_regions.into_iter().flatten() {
|
||||||
let mut impl_blocks =
|
let impl_blocks = region.impl_blocks.into_iter().collect::<SmallVec<[usize; 8]>>();
|
||||||
region.impl_blocks.into_iter().collect::<SmallVec<[usize; 8]>>();
|
|
||||||
impl_blocks.sort_unstable();
|
|
||||||
for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() {
|
for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() {
|
||||||
let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx];
|
let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx];
|
||||||
res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id));
|
res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id));
|
||||||
|
|
|
@ -1627,23 +1627,25 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
|
||||||
pub(crate) struct EffectsWithoutNextSolver;
|
pub(crate) struct EffectsWithoutNextSolver;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)]
|
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
|
||||||
#[note]
|
#[note]
|
||||||
pub(crate) struct CmseCallInputsStackSpill {
|
pub(crate) struct CmseInputsStackSpill {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub plural: bool,
|
pub plural: bool,
|
||||||
|
pub abi_name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)]
|
#[diag(hir_analysis_cmse_output_stack_spill, code = E0798)]
|
||||||
#[note(hir_analysis_note1)]
|
#[note(hir_analysis_note1)]
|
||||||
#[note(hir_analysis_note2)]
|
#[note(hir_analysis_note2)]
|
||||||
pub(crate) struct CmseCallOutputStackSpill {
|
pub(crate) struct CmseOutputStackSpill {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub abi_name: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -1659,3 +1661,10 @@ pub(crate) struct BadReturnTypeNotation {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_cmse_entry_generic, code = E0798)]
|
||||||
|
pub(crate) struct CmseEntryGeneric {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
|
use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err};
|
||||||
use rustc_hir::{self as hir, HirId};
|
use rustc_hir::{self as hir, HirId};
|
||||||
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::layout::LayoutError;
|
use rustc_middle::ty::layout::LayoutError;
|
||||||
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
|
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
|
||||||
use rustc_span::Span;
|
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
@ -17,61 +17,104 @@ pub(crate) fn validate_cmse_abi<'tcx>(
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
fn_sig: ty::PolyFnSig<'tcx>,
|
fn_sig: ty::PolyFnSig<'tcx>,
|
||||||
) {
|
) {
|
||||||
if let abi::Abi::CCmseNonSecureCall = abi {
|
let abi_name = abi.name();
|
||||||
let hir_node = tcx.hir_node(hir_id);
|
|
||||||
let hir::Node::Ty(hir::Ty {
|
match abi {
|
||||||
span: bare_fn_span,
|
abi::Abi::CCmseNonSecureCall => {
|
||||||
kind: hir::TyKind::BareFn(bare_fn_ty),
|
let hir_node = tcx.hir_node(hir_id);
|
||||||
..
|
let hir::Node::Ty(hir::Ty {
|
||||||
}) = hir_node
|
span: bare_fn_span,
|
||||||
else {
|
kind: hir::TyKind::BareFn(bare_fn_ty),
|
||||||
let span = match tcx.parent_hir_node(hir_id) {
|
..
|
||||||
hir::Node::Item(hir::Item {
|
}) = hir_node
|
||||||
kind: hir::ItemKind::ForeignMod { .. }, span, ..
|
else {
|
||||||
}) => *span,
|
let span = match tcx.parent_hir_node(hir_id) {
|
||||||
_ => tcx.hir().span(hir_id),
|
hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::ForeignMod { .. },
|
||||||
|
span,
|
||||||
|
..
|
||||||
|
}) => *span,
|
||||||
|
_ => tcx.hir().span(hir_id),
|
||||||
|
};
|
||||||
|
struct_span_code_err!(
|
||||||
|
tcx.dcx(),
|
||||||
|
span,
|
||||||
|
E0781,
|
||||||
|
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
struct_span_code_err!(
|
|
||||||
tcx.dcx(),
|
|
||||||
span,
|
|
||||||
E0781,
|
|
||||||
"the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
match is_valid_cmse_inputs(tcx, fn_sig) {
|
match is_valid_cmse_inputs(tcx, fn_sig) {
|
||||||
Ok(Ok(())) => {}
|
Ok(Ok(())) => {}
|
||||||
Ok(Err(index)) => {
|
Ok(Err(index)) => {
|
||||||
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
|
// fn(x: u32, u32, u32, u16, y: u16) -> u32,
|
||||||
// ^^^^^^
|
// ^^^^^^
|
||||||
let span = bare_fn_ty.param_names[index]
|
let span = bare_fn_ty.param_names[index]
|
||||||
.span
|
.span
|
||||||
.to(bare_fn_ty.decl.inputs[index].span)
|
.to(bare_fn_ty.decl.inputs[index].span)
|
||||||
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
|
.to(bare_fn_ty.decl.inputs.last().unwrap().span);
|
||||||
let plural = bare_fn_ty.param_names.len() - index != 1;
|
let plural = bare_fn_ty.param_names.len() - index != 1;
|
||||||
dcx.emit_err(errors::CmseCallInputsStackSpill { span, plural });
|
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
|
||||||
}
|
}
|
||||||
Err(layout_err) => {
|
Err(layout_err) => {
|
||||||
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
dcx.emit_err(err);
|
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match is_valid_cmse_output(tcx, fn_sig) {
|
||||||
|
Ok(true) => {}
|
||||||
|
Ok(false) => {
|
||||||
|
let span = bare_fn_ty.decl.output.span();
|
||||||
|
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
|
||||||
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
abi::Abi::CCmseNonSecureEntry => {
|
||||||
|
let hir_node = tcx.hir_node(hir_id);
|
||||||
|
let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else {
|
||||||
|
// might happen when this ABI is used incorrectly. That will be handled elsewhere
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
match is_valid_cmse_output(tcx, fn_sig) {
|
match is_valid_cmse_inputs(tcx, fn_sig) {
|
||||||
Ok(true) => {}
|
Ok(Ok(())) => {}
|
||||||
Ok(false) => {
|
Ok(Err(index)) => {
|
||||||
let span = bare_fn_ty.decl.output.span();
|
// fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32,
|
||||||
dcx.emit_err(errors::CmseCallOutputStackSpill { span });
|
// ^^^^^^
|
||||||
}
|
let span = decl.inputs[index].span.to(decl.inputs.last().unwrap().span);
|
||||||
Err(layout_err) => {
|
let plural = decl.inputs.len() - index != 1;
|
||||||
if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) {
|
dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name });
|
||||||
dcx.emit_err(err);
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
match is_valid_cmse_output(tcx, fn_sig) {
|
||||||
|
Ok(true) => {}
|
||||||
|
Ok(false) => {
|
||||||
|
let span = decl.output.span();
|
||||||
|
dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name });
|
||||||
|
}
|
||||||
|
Err(layout_err) => {
|
||||||
|
if should_emit_generic_error(abi, layout_err) {
|
||||||
|
dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,22 +195,22 @@ fn is_valid_cmse_output<'tcx>(
|
||||||
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
|
Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cmse_layout_err<'tcx>(
|
fn should_emit_generic_error<'tcx>(abi: abi::Abi, layout_err: &'tcx LayoutError<'tcx>) -> bool {
|
||||||
layout_err: &'tcx LayoutError<'tcx>,
|
|
||||||
span: Span,
|
|
||||||
) -> Option<crate::errors::CmseCallGeneric> {
|
|
||||||
use LayoutError::*;
|
use LayoutError::*;
|
||||||
|
|
||||||
match layout_err {
|
match layout_err {
|
||||||
Unknown(ty) => {
|
Unknown(ty) => {
|
||||||
if ty.is_impl_trait() {
|
match abi {
|
||||||
None // prevent double reporting of this error
|
abi::Abi::CCmseNonSecureCall => {
|
||||||
} else {
|
// prevent double reporting of this error
|
||||||
Some(errors::CmseCallGeneric { span })
|
!ty.is_impl_trait()
|
||||||
|
}
|
||||||
|
abi::Abi::CCmseNonSecureEntry => true,
|
||||||
|
_ => bug!("invalid ABI: {abi}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
|
SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => {
|
||||||
None // not our job to report these
|
false // not our job to report these
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ use rustc_ast::util::case::Case;
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
|
self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
|
||||||
GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
|
GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability,
|
||||||
PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind,
|
Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
|
||||||
|
TyKind,
|
||||||
};
|
};
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_span::symbol::{Ident, kw, sym};
|
use rustc_span::symbol::{Ident, kw, sym};
|
||||||
|
@ -487,7 +488,10 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
|
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {
|
||||||
let and_span = self.prev_token.span;
|
let and_span = self.prev_token.span;
|
||||||
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
|
let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime());
|
||||||
let mut mutbl = self.parse_mutability();
|
let (pinned, mut mutbl) = match self.parse_pin_and_mut() {
|
||||||
|
Some(pin_mut) => pin_mut,
|
||||||
|
None => (Pinnedness::Not, self.parse_mutability()),
|
||||||
|
};
|
||||||
if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
|
if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() {
|
||||||
// A lifetime is invalid here: it would be part of a bare trait bound, which requires
|
// A lifetime is invalid here: it would be part of a bare trait bound, which requires
|
||||||
// it to be followed by a plus, but we disallow plus in the pointee type.
|
// it to be followed by a plus, but we disallow plus in the pointee type.
|
||||||
|
@ -523,7 +527,35 @@ impl<'a> Parser<'a> {
|
||||||
self.bump_with((dyn_tok, dyn_tok_sp));
|
self.bump_with((dyn_tok, dyn_tok_sp));
|
||||||
}
|
}
|
||||||
let ty = self.parse_ty_no_plus()?;
|
let ty = self.parse_ty_no_plus()?;
|
||||||
Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }))
|
Ok(match pinned {
|
||||||
|
Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }),
|
||||||
|
Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parses `pin` and `mut` annotations on references.
|
||||||
|
///
|
||||||
|
/// It must be either `pin const` or `pin mut`.
|
||||||
|
pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> {
|
||||||
|
if self.token.is_ident_named(sym::pin) {
|
||||||
|
let result = self.look_ahead(1, |token| {
|
||||||
|
if token.is_keyword(kw::Const) {
|
||||||
|
Some((Pinnedness::Pinned, Mutability::Not))
|
||||||
|
} else if token.is_keyword(kw::Mut) {
|
||||||
|
Some((Pinnedness::Pinned, Mutability::Mut))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if result.is_some() {
|
||||||
|
self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
|
||||||
|
self.bump();
|
||||||
|
self.bump();
|
||||||
|
}
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses the `typeof(EXPR)`.
|
// Parses the `typeof(EXPR)`.
|
||||||
|
|
|
@ -579,6 +579,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
Array,
|
Array,
|
||||||
Ptr,
|
Ptr,
|
||||||
Ref,
|
Ref,
|
||||||
|
PinnedRef,
|
||||||
BareFn,
|
BareFn,
|
||||||
Never,
|
Never,
|
||||||
Tup,
|
Tup,
|
||||||
|
|
|
@ -779,7 +779,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
|
||||||
let prev = self.diag_metadata.current_trait_object;
|
let prev = self.diag_metadata.current_trait_object;
|
||||||
let prev_ty = self.diag_metadata.current_type_path;
|
let prev_ty = self.diag_metadata.current_type_path;
|
||||||
match &ty.kind {
|
match &ty.kind {
|
||||||
TyKind::Ref(None, _) => {
|
TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => {
|
||||||
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
|
// Elided lifetime in reference: we resolve as if there was some lifetime `'_` with
|
||||||
// NodeId `ty.id`.
|
// NodeId `ty.id`.
|
||||||
// This span will be used in case of elision failure.
|
// This span will be used in case of elision failure.
|
||||||
|
@ -2326,7 +2326,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
||||||
impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
|
impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
|
||||||
fn visit_ty(&mut self, ty: &'ra Ty) {
|
fn visit_ty(&mut self, ty: &'ra Ty) {
|
||||||
trace!("FindReferenceVisitor considering ty={:?}", ty);
|
trace!("FindReferenceVisitor considering ty={:?}", ty);
|
||||||
if let TyKind::Ref(lt, _) = ty.kind {
|
if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind {
|
||||||
// See if anything inside the &thing contains Self
|
// See if anything inside the &thing contains Self
|
||||||
let mut visitor =
|
let mut visitor =
|
||||||
SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false };
|
SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false };
|
||||||
|
|
|
@ -3482,7 +3482,7 @@ struct LifetimeFinder<'ast> {
|
||||||
|
|
||||||
impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> {
|
impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> {
|
||||||
fn visit_ty(&mut self, t: &'ast Ty) {
|
fn visit_ty(&mut self, t: &'ast Ty) {
|
||||||
if let TyKind::Ref(_, mut_ty) = &t.kind {
|
if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind {
|
||||||
self.seen.push(t);
|
self.seen.push(t);
|
||||||
if t.span.lo() == self.lifetime.lo() {
|
if t.span.lo() == self.lifetime.lo() {
|
||||||
self.found = Some(&mut_ty.ty);
|
self.found = Some(&mut_ty.ty);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use core::borrow::Borrow;
|
||||||
use core::ffi::{CStr, c_char};
|
use core::ffi::{CStr, c_char};
|
||||||
use core::num::NonZero;
|
use core::num::NonZero;
|
||||||
use core::slice::memchr;
|
use core::slice::memchr;
|
||||||
use core::str::{self, Utf8Error};
|
use core::str::{self, FromStr, Utf8Error};
|
||||||
use core::{fmt, mem, ops, ptr, slice};
|
use core::{fmt, mem, ops, ptr, slice};
|
||||||
|
|
||||||
use crate::borrow::{Cow, ToOwned};
|
use crate::borrow::{Cow, ToOwned};
|
||||||
|
@ -817,6 +817,30 @@ impl From<Vec<NonZero<u8>>> for CString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for CString {
|
||||||
|
type Err = NulError;
|
||||||
|
|
||||||
|
/// Converts a string `s` into a [`CString`].
|
||||||
|
///
|
||||||
|
/// This method is equivalent to [`CString::new`].
|
||||||
|
#[inline]
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Self::new(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<CString> for String {
|
||||||
|
type Error = IntoStringError;
|
||||||
|
|
||||||
|
/// Converts a [`CString`] into a [`String`] if it contains valid UTF-8 data.
|
||||||
|
///
|
||||||
|
/// This method is equivalent to [`CString::into_string`].
|
||||||
|
#[inline]
|
||||||
|
fn try_from(value: CString) -> Result<Self, Self::Error> {
|
||||||
|
value.into_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
|
#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
|
||||||
impl Clone for Box<CStr> {
|
impl Clone for Box<CStr> {
|
||||||
|
|
|
@ -1282,8 +1282,9 @@ impl char {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase
|
/// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_uppercase(&mut self) {
|
pub const fn make_ascii_uppercase(&mut self) {
|
||||||
*self = self.to_ascii_uppercase();
|
*self = self.to_ascii_uppercase();
|
||||||
}
|
}
|
||||||
|
@ -1308,8 +1309,9 @@ impl char {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase
|
/// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_lowercase(&mut self) {
|
pub const fn make_ascii_lowercase(&mut self) {
|
||||||
*self = self.to_ascii_lowercase();
|
*self = self.to_ascii_lowercase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,6 @@
|
||||||
#![feature(const_heap)]
|
#![feature(const_heap)]
|
||||||
#![feature(const_index_range_slice_index)]
|
#![feature(const_index_range_slice_index)]
|
||||||
#![feature(const_likely)]
|
#![feature(const_likely)]
|
||||||
#![feature(const_make_ascii)]
|
|
||||||
#![feature(const_nonnull_new)]
|
#![feature(const_nonnull_new)]
|
||||||
#![feature(const_num_midpoint)]
|
#![feature(const_num_midpoint)]
|
||||||
#![feature(const_option_ext)]
|
#![feature(const_option_ext)]
|
||||||
|
|
|
@ -624,8 +624,9 @@ impl u8 {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_uppercase`]: Self::to_ascii_uppercase
|
/// [`to_ascii_uppercase`]: Self::to_ascii_uppercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_uppercase(&mut self) {
|
pub const fn make_ascii_uppercase(&mut self) {
|
||||||
*self = self.to_ascii_uppercase();
|
*self = self.to_ascii_uppercase();
|
||||||
}
|
}
|
||||||
|
@ -650,8 +651,9 @@ impl u8 {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_lowercase`]: Self::to_ascii_lowercase
|
/// [`to_ascii_lowercase`]: Self::to_ascii_lowercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_lowercase(&mut self) {
|
pub const fn make_ascii_lowercase(&mut self) {
|
||||||
*self = self.to_ascii_lowercase();
|
*self = self.to_ascii_lowercase();
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,8 +67,9 @@ impl [u8] {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
|
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_uppercase(&mut self) {
|
pub const fn make_ascii_uppercase(&mut self) {
|
||||||
// FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions.
|
// FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions.
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -89,8 +90,9 @@ impl [u8] {
|
||||||
///
|
///
|
||||||
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
|
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_lowercase(&mut self) {
|
pub const fn make_ascii_lowercase(&mut self) {
|
||||||
// FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions.
|
// FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions.
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
|
@ -2475,8 +2475,9 @@ impl str {
|
||||||
/// assert_eq!("GRüßE, JüRGEN ❤", s);
|
/// assert_eq!("GRüßE, JüRGEN ❤", s);
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_uppercase(&mut self) {
|
pub const fn make_ascii_uppercase(&mut self) {
|
||||||
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
||||||
let me = unsafe { self.as_bytes_mut() };
|
let me = unsafe { self.as_bytes_mut() };
|
||||||
|
@ -2503,8 +2504,9 @@ impl str {
|
||||||
/// assert_eq!("grÜße, jÜrgen ❤", s);
|
/// assert_eq!("grÜße, jÜrgen ❤", s);
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
|
||||||
#[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")]
|
#[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||||
pub const fn make_ascii_lowercase(&mut self) {
|
pub const fn make_ascii_lowercase(&mut self) {
|
||||||
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
// SAFETY: changing ASCII letters only does not invalidate UTF-8.
|
||||||
let me = unsafe { self.as_bytes_mut() };
|
let me = unsafe { self.as_bytes_mut() };
|
||||||
|
|
|
@ -213,11 +213,9 @@ impl Duration {
|
||||||
// SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
|
// SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
|
||||||
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
|
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
|
||||||
} else {
|
} else {
|
||||||
// FIXME(const-hack): use `.expect` once that is possible.
|
let secs = secs
|
||||||
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
|
.checked_add((nanos / NANOS_PER_SEC) as u64)
|
||||||
Some(secs) => secs,
|
.expect("overflow in Duration::new");
|
||||||
None => panic!("overflow in Duration::new"),
|
|
||||||
};
|
|
||||||
let nanos = nanos % NANOS_PER_SEC;
|
let nanos = nanos % NANOS_PER_SEC;
|
||||||
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
|
// SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
|
||||||
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
|
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
|
||||||
|
|
|
@ -18,17 +18,6 @@ use crate::sys_common::AsInner;
|
||||||
use crate::sys_common::wstr::WStrUnits;
|
use crate::sys_common::wstr::WStrUnits;
|
||||||
use crate::{fmt, io, iter, vec};
|
use crate::{fmt, io, iter, vec};
|
||||||
|
|
||||||
/// This is the const equivalent to `NonZero::new(n).unwrap()`
|
|
||||||
///
|
|
||||||
/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const.
|
|
||||||
/// See the `const_option` feature (#67441).
|
|
||||||
const fn non_zero_u16(n: u16) -> NonZero<u16> {
|
|
||||||
match NonZero::new(n) {
|
|
||||||
Some(n) => n,
|
|
||||||
None => panic!("called `unwrap` on a `None` value"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
// SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16
|
// SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16
|
||||||
// string so it's safe for `WStrUnits` to use.
|
// string so it's safe for `WStrUnits` to use.
|
||||||
|
@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>(
|
||||||
lp_cmd_line: Option<WStrUnits<'a>>,
|
lp_cmd_line: Option<WStrUnits<'a>>,
|
||||||
exe_name: F,
|
exe_name: F,
|
||||||
) -> Vec<OsString> {
|
) -> Vec<OsString> {
|
||||||
const BACKSLASH: NonZero<u16> = non_zero_u16(b'\\' as u16);
|
const BACKSLASH: NonZero<u16> = NonZero::new(b'\\' as u16).unwrap();
|
||||||
const QUOTE: NonZero<u16> = non_zero_u16(b'"' as u16);
|
const QUOTE: NonZero<u16> = NonZero::new(b'"' as u16).unwrap();
|
||||||
const TAB: NonZero<u16> = non_zero_u16(b'\t' as u16);
|
const TAB: NonZero<u16> = NonZero::new(b'\t' as u16).unwrap();
|
||||||
const SPACE: NonZero<u16> = non_zero_u16(b' ' as u16);
|
const SPACE: NonZero<u16> = NonZero::new(b' ' as u16).unwrap();
|
||||||
|
|
||||||
let mut ret_val = Vec::new();
|
let mut ret_val = Vec::new();
|
||||||
// If the cmd line pointer is null or it points to an empty string then
|
// If the cmd line pointer is null or it points to an empty string then
|
||||||
|
|
|
@ -753,6 +753,9 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
|
||||||
(Ref(ll, l), Ref(rl, r)) => {
|
(Ref(ll, l), Ref(rl, r)) => {
|
||||||
both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
|
both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
|
||||||
},
|
},
|
||||||
|
(PinnedRef(ll, l), PinnedRef(rl, r)) => {
|
||||||
|
both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
|
||||||
|
},
|
||||||
(BareFn(l), BareFn(r)) => {
|
(BareFn(l), BareFn(r)) => {
|
||||||
l.safety == r.safety
|
l.safety == r.safety
|
||||||
&& eq_ext(&l.ext, &r.ext)
|
&& eq_ext(&l.ext, &r.ext)
|
||||||
|
|
|
@ -827,7 +827,8 @@ impl Rewrite for ast::Ty {
|
||||||
|
|
||||||
rewrite_unary_prefix(context, prefix, &*mt.ty, shape)
|
rewrite_unary_prefix(context, prefix, &*mt.ty, shape)
|
||||||
}
|
}
|
||||||
ast::TyKind::Ref(ref lifetime, ref mt) => {
|
ast::TyKind::Ref(ref lifetime, ref mt)
|
||||||
|
| ast::TyKind::PinnedRef(ref lifetime, ref mt) => {
|
||||||
let mut_str = format_mutability(mt.mutbl);
|
let mut_str = format_mutability(mt.mutbl);
|
||||||
let mut_len = mut_str.len();
|
let mut_len = mut_str.len();
|
||||||
let mut result = String::with_capacity(128);
|
let mut result = String::with_capacity(128);
|
||||||
|
@ -861,6 +862,13 @@ impl Rewrite for ast::Ty {
|
||||||
cmnt_lo = lifetime.ident.span.hi();
|
cmnt_lo = lifetime.ident.span.hi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let ast::TyKind::PinnedRef(..) = self.kind {
|
||||||
|
result.push_str("pin ");
|
||||||
|
if ast::Mutability::Not == mt.mutbl {
|
||||||
|
result.push_str("const ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ast::Mutability::Mut == mt.mutbl {
|
if ast::Mutability::Mut == mt.mutbl {
|
||||||
let mut_hi = context.snippet_provider.span_after(self.span(), "mut");
|
let mut_hi = context.snippet_provider.span_after(self.span(), "mut");
|
||||||
let before_mut_span = mk_sp(cmnt_lo, mut_hi - BytePos::from_usize(3));
|
let before_mut_span = mk_sp(cmnt_lo, mut_hi - BytePos::from_usize(3));
|
||||||
|
@ -1260,9 +1268,9 @@ pub(crate) fn can_be_overflowed_type(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
ast::TyKind::Tup(..) => context.use_block_indent() && len == 1,
|
ast::TyKind::Tup(..) => context.use_block_indent() && len == 1,
|
||||||
ast::TyKind::Ref(_, ref mutty) | ast::TyKind::Ptr(ref mutty) => {
|
ast::TyKind::Ref(_, ref mutty)
|
||||||
can_be_overflowed_type(context, &*mutty.ty, len)
|
| ast::TyKind::PinnedRef(_, ref mutty)
|
||||||
}
|
| ast::TyKind::Ptr(ref mutty) => can_be_overflowed_type(context, &*mutty.ty, len),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/tools/rustfmt/tests/source/pin_sugar.rs
Normal file
10
src/tools/rustfmt/tests/source/pin_sugar.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// See #130494
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn f(x: &pin const i32) {}
|
||||||
|
fn g<'a>(x: & 'a pin const i32) {}
|
||||||
|
fn h<'a>(x: & 'a pin
|
||||||
|
mut i32) {}
|
||||||
|
fn i(x: &pin mut i32) {}
|
9
src/tools/rustfmt/tests/target/pin_sugar.rs
Normal file
9
src/tools/rustfmt/tests/target/pin_sugar.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// See #130494
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn f(x: &pin const i32) {}
|
||||||
|
fn g<'a>(x: &'a pin const i32) {}
|
||||||
|
fn h<'a>(x: &'a pin mut i32) {}
|
||||||
|
fn i(x: &pin mut i32) {}
|
15
tests/ui/async-await/pin-sugar-ambiguity.rs
Normal file
15
tests/ui/async-await/pin-sugar-ambiguity.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
//@ check-pass
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
// Handle the case where there's ambiguity between pin as a contextual keyword and pin as a path.
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
mod pin {
|
||||||
|
pub struct Foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _x: &pin ::Foo = &pin::Foo;
|
||||||
|
}
|
8
tests/ui/async-await/pin-sugar-no-const.rs
Normal file
8
tests/ui/async-await/pin-sugar-no-const.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
// Makes sure we don't accidentally accept `&pin Foo` without the `const` keyword.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _x: &pin i32 = todo!(); //~ ERROR found `i32`
|
||||||
|
}
|
15
tests/ui/async-await/pin-sugar-no-const.stderr
Normal file
15
tests/ui/async-await/pin-sugar-no-const.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error: expected one of `!`, `(`, `::`, `;`, `<`, or `=`, found `i32`
|
||||||
|
--> $DIR/pin-sugar-no-const.rs:7:18
|
||||||
|
|
|
||||||
|
LL | let _x: &pin i32 = todo!();
|
||||||
|
| - ^^^ expected one of `!`, `(`, `::`, `;`, `<`, or `=`
|
||||||
|
| |
|
||||||
|
| while parsing the type for `_x`
|
||||||
|
|
|
||||||
|
help: there is a keyword `in` with a similar name
|
||||||
|
|
|
||||||
|
LL | let _x: &in i32 = todo!();
|
||||||
|
| ~~
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
51
tests/ui/async-await/pin-sugar.rs
Normal file
51
tests/ui/async-await/pin-sugar.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(pin_ergonomics)]
|
||||||
|
#![allow(dead_code, incomplete_features)]
|
||||||
|
|
||||||
|
// Makes sure we can handle `&pin mut T` and `&pin const T` as sugar for `Pin<&mut T>` and
|
||||||
|
// `Pin<&T>`.
|
||||||
|
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn baz(self: &pin mut Self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz_const(self: &pin const Self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz_lt<'a>(self: &'a pin mut Self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz_const_lt(self: &'_ pin const Self) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: &pin mut Foo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo_const(x: &pin const Foo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: &pin mut Foo) {
|
||||||
|
foo(x);
|
||||||
|
foo(x); // for this to work we need to automatically reborrow,
|
||||||
|
// as if the user had written `foo(x.as_mut())`.
|
||||||
|
|
||||||
|
Foo::baz(x);
|
||||||
|
Foo::baz(x);
|
||||||
|
|
||||||
|
// make sure we can reborrow &mut as &.
|
||||||
|
foo_const(x);
|
||||||
|
Foo::baz_const(x);
|
||||||
|
|
||||||
|
let x: &pin const _ = Pin::new(&Foo);
|
||||||
|
|
||||||
|
foo_const(x); // make sure reborrowing from & to & works.
|
||||||
|
foo_const(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
77
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
Normal file
77
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
pub trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct Wrapper<T>(T);
|
||||||
|
|
||||||
|
impl<T: Copy> Wrapper<T> {
|
||||||
|
extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
_: Wrapper<T>,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
_: U,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
_: u32,
|
||||||
|
) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn reference(x: &usize) -> usize {
|
||||||
|
*x
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn static_trait_object(
|
||||||
|
x: &'static dyn Trait,
|
||||||
|
) -> &'static dyn Trait {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
struct WrapperTransparent<'a>(&'a dyn Trait);
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn wrapped_trait_object(
|
||||||
|
x: WrapperTransparent,
|
||||||
|
) -> WrapperTransparent {
|
||||||
|
//~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798]
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
|
||||||
|
//~| ERROR requires `va_list` lang_item
|
||||||
|
}
|
78
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
Normal file
78
tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg
|
||||||
|
--> $DIR/generics.rs:74:55
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / extern "C-cmse-nonsecure-entry" fn introduced_generic<U: Copy>(
|
||||||
|
LL | |
|
||||||
|
LL | | _: U,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | ) -> u64 {
|
||||||
|
| |________^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:41:1
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:15:5
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type
|
||||||
|
--> $DIR/generics.rs:20:5
|
||||||
|
|
|
||||||
|
LL | / extern "C-cmse-nonsecure-entry" fn ambient_generic_nested(
|
||||||
|
LL | |
|
||||||
|
LL | | _: Wrapper<T>,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | _: u32,
|
||||||
|
LL | | ) -> u64 {
|
||||||
|
| |____________^
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:52:67
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait {
|
||||||
|
| ^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:59:6
|
||||||
|
|
|
||||||
|
LL | ) -> &'static dyn Trait {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/generics.rs:69:6
|
||||||
|
|
|
||||||
|
LL | ) -> WrapperTransparent {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error: requires `va_list` lang_item
|
||||||
|
--> $DIR/generics.rs:74:55
|
||||||
|
|
|
||||||
|
LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) {
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
|
@ -1,16 +0,0 @@
|
||||||
//@ build-pass
|
|
||||||
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
|
||||||
//@ needs-llvm-components: arm
|
|
||||||
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
|
||||||
#![no_core]
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
impl Copy for u32 {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C-cmse-nonsecure-entry" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 {
|
|
||||||
d
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
//@ build-fail
|
|
||||||
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
|
||||||
//@ needs-llvm-components: arm
|
|
||||||
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
|
||||||
#![no_core]
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
impl Copy for u32 {}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C-cmse-nonsecure-entry" fn entry_function(
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
_: u32,
|
|
||||||
e: u32,
|
|
||||||
) -> u32 {
|
|
||||||
e
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
error: <unknown>:0:0: in function entry_function i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
#[allow(unused)]
|
||||||
|
pub struct AlignRelevant(u32);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} //~ ERROR [E0798]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} //~ ERROR [E0798]
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798]
|
|
@ -0,0 +1,43 @@
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:16:78
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {}
|
||||||
|
| ^^^^^^^^^^^ these arguments don't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:18:78
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:20:62
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:22:64
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {}
|
||||||
|
| ^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/params-via-stack.rs:26:46
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {}
|
||||||
|
| ^^^^^^^^ this argument doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
|
@ -0,0 +1,84 @@
|
||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
pub trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
impl Copy for u8 {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ReprCU64(u64);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ReprCBytes(u8, u8, u8, u8, u8);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct U64Compound(u32, u32);
|
||||||
|
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
pub struct ReprCAlign16(u16);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCU64(0)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCBytes(0, 1, 2, 3, 4)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
U64Compound(2, 3)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCAlign16(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
[0xAA; 5]
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
123
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
456
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(Rust)]
|
||||||
|
pub union ReprRustUnionU64 {
|
||||||
|
_unused: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub union ReprCUnionU64 {
|
||||||
|
_unused: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprRustUnionU64 { _unused: 1 }
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
|
||||||
|
//~^ ERROR [E0798]
|
||||||
|
ReprCUnionU64 { _unused: 2 }
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:25:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 {
|
||||||
|
| ^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:30:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes {
|
||||||
|
| ^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:35:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound {
|
||||||
|
| ^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:40:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 {
|
||||||
|
| ^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:47:48
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] {
|
||||||
|
| ^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:53:50
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 {
|
||||||
|
| ^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:59:50
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 {
|
||||||
|
| ^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:76:56
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 {
|
||||||
|
| ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers
|
||||||
|
--> $DIR/return-via-stack.rs:81:53
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 {
|
||||||
|
| ^^^^^^^^^^^^^ this type doesn't fit in the available registers
|
||||||
|
|
|
||||||
|
= note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers
|
||||||
|
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0798`.
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target
|
||||||
|
--> $DIR/trustzone-only.rs:5:1
|
||||||
|
|
|
||||||
|
LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0570`.
|
|
@ -0,0 +1,89 @@
|
||||||
|
//@ build-pass
|
||||||
|
//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib
|
||||||
|
//@ needs-llvm-components: arm
|
||||||
|
#![feature(cmse_nonsecure_entry, no_core, lang_items)]
|
||||||
|
#![no_core]
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized {}
|
||||||
|
#[lang = "copy"]
|
||||||
|
trait Copy {}
|
||||||
|
impl Copy for u32 {}
|
||||||
|
impl Copy for u8 {}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct ReprTransparentStruct<T> {
|
||||||
|
_marker1: (),
|
||||||
|
_marker2: (),
|
||||||
|
field: T,
|
||||||
|
_marker3: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub enum ReprTransparentEnumU64 {
|
||||||
|
A(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct U32Compound(u16, u16);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs1() {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs2(_: u32, _: u32, _: u32, _: u32) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs3(_: u64, _: u64) {}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs4(_: u128) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs5(_: f64, _: f32, _: f32) {}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs6(_: ReprTransparentStruct<u64>, _: U32Compound) {}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn inputs7(_: [u32; 4]) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs1() -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs2() -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs3() -> i64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs4() -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
#[allow(improper_ctypes_definitions)]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs5() -> [u8; 4] {
|
||||||
|
[0xAA; 4]
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs6() -> ReprTransparentStruct<u64> {
|
||||||
|
ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () }
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs7(
|
||||||
|
) -> ReprTransparentStruct<ReprTransparentStruct<u64>> {
|
||||||
|
ReprTransparentStruct {
|
||||||
|
_marker1: (),
|
||||||
|
_marker2: (),
|
||||||
|
field: ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () },
|
||||||
|
_marker3: (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs8() -> ReprTransparentEnumU64 {
|
||||||
|
ReprTransparentEnumU64::A(0)
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C-cmse-nonsecure-entry" fn outputs9() -> U32Compound {
|
||||||
|
U32Compound(1, 2)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#![allow(dead_code, incomplete_features)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
@ -9,10 +9,13 @@ impl Foo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo(_: Pin<&mut Foo>) {
|
fn foo(x: Pin<&mut Foo>) {
|
||||||
|
let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar(mut x: Pin<&mut Foo>) {
|
fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental
|
||||||
|
|
||||||
|
fn bar(x: Pin<&mut Foo>) {
|
||||||
foo(x);
|
foo(x);
|
||||||
foo(x); //~ ERROR use of moved value: `x`
|
foo(x); //~ ERROR use of moved value: `x`
|
||||||
}
|
}
|
||||||
|
@ -22,4 +25,6 @@ fn baz(mut x: Pin<&mut Foo>) {
|
||||||
x.foo(); //~ ERROR use of moved value: `x`
|
x.foo(); //~ ERROR use of moved value: `x`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,38 @@
|
||||||
error[E0382]: use of moved value: `x`
|
error[E0658]: pinned reference syntax is experimental
|
||||||
--> $DIR/feature-gate-pin_ergonomics.rs:17:9
|
--> $DIR/feature-gate-pin_ergonomics.rs:13:14
|
||||||
|
|
|
|
||||||
LL | fn bar(mut x: Pin<&mut Foo>) {
|
LL | let _y: &pin mut Foo = x;
|
||||||
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
|
||||||
|
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0658]: pinned reference syntax is experimental
|
||||||
|
--> $DIR/feature-gate-pin_ergonomics.rs:16:18
|
||||||
|
|
|
||||||
|
LL | fn foo_sugar(_: &pin mut Foo) {}
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
|
||||||
|
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0658]: pinned reference syntax is experimental
|
||||||
|
--> $DIR/feature-gate-pin_ergonomics.rs:28:18
|
||||||
|
|
|
||||||
|
LL | fn baz_sugar(_: &pin const Foo) {}
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
|
||||||
|
= help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable
|
||||||
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
|
error[E0382]: use of moved value: `x`
|
||||||
|
--> $DIR/feature-gate-pin_ergonomics.rs:20:9
|
||||||
|
|
|
||||||
|
LL | fn bar(x: Pin<&mut Foo>) {
|
||||||
|
| - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||||
LL | foo(x);
|
LL | foo(x);
|
||||||
| - value moved here
|
| - value moved here
|
||||||
LL | foo(x);
|
LL | foo(x);
|
||||||
|
@ -11,13 +41,13 @@ LL | foo(x);
|
||||||
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
|
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
|
||||||
--> $DIR/feature-gate-pin_ergonomics.rs:12:11
|
--> $DIR/feature-gate-pin_ergonomics.rs:12:11
|
||||||
|
|
|
|
||||||
LL | fn foo(_: Pin<&mut Foo>) {
|
LL | fn foo(x: Pin<&mut Foo>) {
|
||||||
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
|
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
|
||||||
| |
|
| |
|
||||||
| in this function
|
| in this function
|
||||||
|
|
||||||
error[E0382]: use of moved value: `x`
|
error[E0382]: use of moved value: `x`
|
||||||
--> $DIR/feature-gate-pin_ergonomics.rs:22:5
|
--> $DIR/feature-gate-pin_ergonomics.rs:25:5
|
||||||
|
|
|
|
||||||
LL | fn baz(mut x: Pin<&mut Foo>) {
|
LL | fn baz(mut x: Pin<&mut Foo>) {
|
||||||
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||||
|
@ -36,6 +66,7 @@ help: consider reborrowing the `Pin` instead of moving it
|
||||||
LL | x.as_mut().foo();
|
LL | x.as_mut().foo();
|
||||||
| +++++++++
|
| +++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0382`.
|
Some errors have detailed explanations: E0382, E0658.
|
||||||
|
For more information about an error, try `rustc --explain E0382`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue