Merge pull request #4049 from rust-lang/rustup-2024-11-22
Automatic Rustup
This commit is contained in:
commit
76f27aaa6f
106 changed files with 2393 additions and 449 deletions
|
|
@ -1965,9 +1965,9 @@ checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.161"
|
||||
version = "0.2.164"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||
|
||||
[[package]]
|
||||
name = "libdbus-sys"
|
||||
|
|
@ -3685,6 +3685,8 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"rustc_data_structures",
|
||||
"rustc_span",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3988,6 +3990,7 @@ name = "rustc_metadata"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"libc",
|
||||
"libloading",
|
||||
"odht",
|
||||
"rustc_abi",
|
||||
|
|
|
|||
234
RELEASES.md
234
RELEASES.md
|
|
@ -1,3 +1,235 @@
|
|||
Version 1.83.0 (2024-11-28)
|
||||
==========================
|
||||
|
||||
<a id="1.83.0-Language"></a>
|
||||
|
||||
Language
|
||||
--------
|
||||
- [Stabilize `&mut`, `*mut`, `&Cell`, and `*const Cell` in const.](https://github.com/rust-lang/rust/pull/129195)
|
||||
- [Allow creating references to statics in `const` initializers.](https://github.com/rust-lang/rust/pull/129759)
|
||||
- [Implement raw lifetimes and labels (`'r#ident`).](https://github.com/rust-lang/rust/pull/126452)
|
||||
- [Define behavior when atomic and non-atomic reads race.](https://github.com/rust-lang/rust/pull/128778)
|
||||
- [Non-exhaustive structs may now be empty.](https://github.com/rust-lang/rust/pull/128934)
|
||||
- [Disallow implicit coercions from places of type `!`](https://github.com/rust-lang/rust/pull/129392)
|
||||
- [`const extern` functions can now be defined for other calling conventions.](https://github.com/rust-lang/rust/pull/129753)
|
||||
- [Stabilize `expr_2021` macro fragment specifier in all editions.](https://github.com/rust-lang/rust/pull/129972)
|
||||
- [The `non_local_definitions` lint now fires on less code and warns by default.](https://github.com/rust-lang/rust/pull/127117)
|
||||
|
||||
|
||||
<a id="1.83.0-Compiler"></a>
|
||||
|
||||
Compiler
|
||||
--------
|
||||
- [Deprecate unsound `-Csoft-float` flag.](https://github.com/rust-lang/rust/pull/129897)
|
||||
- Add many new tier 3 targets:
|
||||
- [`aarch64_unknown_nto_qnx700`](https://github.com/rust-lang/rust/pull/127897)
|
||||
- [`arm64e-apple-tvos`](https://github.com/rust-lang/rust/pull/130614)
|
||||
- [`armv7-rtems-eabihf`](https://github.com/rust-lang/rust/pull/127021)
|
||||
- [`loongarch64-unknown-linux-ohos`](https://github.com/rust-lang/rust/pull/130750)
|
||||
- [`riscv32-wrs-vxworks` and `riscv64-wrs-vxworks`](https://github.com/rust-lang/rust/pull/130549)
|
||||
- [`riscv32{e|em|emc}-unknown-none-elf`](https://github.com/rust-lang/rust/pull/130555)
|
||||
- [`x86_64-unknown-hurd-gnu`](https://github.com/rust-lang/rust/pull/128345)
|
||||
- [`x86_64-unknown-trusty`](https://github.com/rust-lang/rust/pull/130453)
|
||||
|
||||
Refer to Rust's [platform support page][platform-support-doc]
|
||||
for more information on Rust's tiered platform support.
|
||||
|
||||
|
||||
<a id="1.83.0-Libraries"></a>
|
||||
|
||||
Libraries
|
||||
---------
|
||||
- [Implement `PartialEq` for `ExitCode`.](https://github.com/rust-lang/rust/pull/127633)
|
||||
- [Document that `catch_unwind` can deal with foreign exceptions without UB, although the exact behavior is unspecified.](https://github.com/rust-lang/rust/pull/128321)
|
||||
- [Implement `Default` for `HashMap`/`HashSet` iterators that don't already have it.](https://github.com/rust-lang/rust/pull/128711)
|
||||
- [Bump Unicode to version 16.0.0.](https://github.com/rust-lang/rust/pull/130183)
|
||||
- [Change documentation of `ptr::add`/`sub` to not claim equivalence with `offset`.](https://github.com/rust-lang/rust/pull/130229).
|
||||
|
||||
|
||||
<a id="1.83.0-Stabilized-APIs"></a>
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`BufRead::skip_until`](https://doc.rust-lang.org/stable/std/io/trait.BufRead.html#method.skip_until)
|
||||
- [`ControlFlow::break_value`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.break_value)
|
||||
- [`ControlFlow::continue_value`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.continue_value)
|
||||
- [`ControlFlow::map_break`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.map_break)
|
||||
- [`ControlFlow::map_continue`](https://doc.rust-lang.org/stable/core/ops/enum.ControlFlow.html#method.map_continue)
|
||||
- [`DebugList::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugList.html#method.finish_non_exhaustive)
|
||||
- [`DebugMap::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugMap.html#method.finish_non_exhaustive)
|
||||
- [`DebugSet::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugSet.html#method.finish_non_exhaustive)
|
||||
- [`DebugTuple::finish_non_exhaustive`](https://doc.rust-lang.org/stable/core/fmt/struct.DebugTuple.html#method.finish_non_exhaustive)
|
||||
- [`ErrorKind::ArgumentListTooLong`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ArgumentListTooLong)
|
||||
- [`ErrorKind::Deadlock`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.Deadlock)
|
||||
- [`ErrorKind::DirectoryNotEmpty`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.DirectoryNotEmpty)
|
||||
- [`ErrorKind::ExecutableFileBusy`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ExecutableFileBusy)
|
||||
- [`ErrorKind::FileTooLarge`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.FileTooLarge)
|
||||
- [`ErrorKind::HostUnreachable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.HostUnreachable)
|
||||
- [`ErrorKind::IsADirectory`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.IsADirectory)
|
||||
- [`ErrorKind::NetworkDown`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NetworkDown)
|
||||
- [`ErrorKind::NetworkUnreachable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NetworkUnreachable)
|
||||
- [`ErrorKind::NotADirectory`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NotADirectory)
|
||||
- [`ErrorKind::NotSeekable`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.NotSeekable)
|
||||
- [`ErrorKind::ReadOnlyFilesystem`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ReadOnlyFilesystem)
|
||||
- [`ErrorKind::ResourceBusy`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.ResourceBusy)
|
||||
- [`ErrorKind::StaleNetworkFileHandle`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.StaleNetworkFileHandle)
|
||||
- [`ErrorKind::StorageFull`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.StorageFull)
|
||||
- [`ErrorKind::TooManyLinks`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.TooManyLinks)
|
||||
- [`Option::get_or_insert_default`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.get_or_insert_default)
|
||||
- [`Waker::data`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.data)
|
||||
- [`Waker::new`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.new)
|
||||
- [`Waker::vtable`](https://doc.rust-lang.org/stable/core/task/struct.Waker.html#method.vtable)
|
||||
- [`char::MIN`](https://doc.rust-lang.org/stable/core/primitive.char.html#associatedconstant.MIN)
|
||||
- [`hash_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/hash_map/enum.Entry.html#method.insert_entry)
|
||||
- [`hash_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/hash_map/struct.VacantEntry.html#method.insert_entry)
|
||||
|
||||
These APIs are now stable in const contexts:
|
||||
|
||||
- [`Cell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.Cell.html#method.into_inner)
|
||||
- [`Duration::as_secs_f32`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.as_secs_f32)
|
||||
- [`Duration::as_secs_f64`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.as_secs_f64)
|
||||
- [`Duration::div_duration_f32`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.div_duration_f32)
|
||||
- [`Duration::div_duration_f64`](https://doc.rust-lang.org/stable/core/time/struct.Duration.html#method.div_duration_f64)
|
||||
- [`MaybeUninit::as_mut_ptr`](https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.as_mut_ptr)
|
||||
- [`NonNull::as_mut`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_mut)
|
||||
- [`NonNull::copy_from`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_from)
|
||||
- [`NonNull::copy_from_nonoverlapping`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_from_nonoverlapping)
|
||||
- [`NonNull::copy_to`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_to)
|
||||
- [`NonNull::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.copy_to_nonoverlapping)
|
||||
- [`NonNull::slice_from_raw_parts`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.slice_from_raw_parts)
|
||||
- [`NonNull::write`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write)
|
||||
- [`NonNull::write_bytes`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write_bytes)
|
||||
- [`NonNull::write_unaligned`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.write_unaligned)
|
||||
- [`OnceCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.OnceCell.html#method.into_inner)
|
||||
- [`Option::as_mut`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.as_mut)
|
||||
- [`Option::expect`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.expect)
|
||||
- [`Option::replace`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.replace)
|
||||
- [`Option::take`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.take)
|
||||
- [`Option::unwrap`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.unwrap)
|
||||
- [`Option::unwrap_unchecked`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.unwrap_unchecked)
|
||||
- [`Option::<&_>::copied`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.copied)
|
||||
- [`Option::<&mut _>::copied`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.copied-1)
|
||||
- [`Option::<Option<_>>::flatten`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.flatten)
|
||||
- [`Option::<Result<_, _>>::transpose`](https://doc.rust-lang.org/stable/core/option/enum.Option.html#method.transpose)
|
||||
- [`RefCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.RefCell.html#method.into_inner)
|
||||
- [`Result::as_mut`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.as_mut)
|
||||
- [`Result::<&_, _>::copied`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.copied)
|
||||
- [`Result::<&mut _, _>::copied`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.copied-1)
|
||||
- [`Result::<Option<_>, _>::transpose`](https://doc.rust-lang.org/stable/core/result/enum.Result.html#method.transpose)
|
||||
- [`UnsafeCell::get_mut`](https://doc.rust-lang.org/stable/core/cell/struct.UnsafeCell.html#method.get_mut)
|
||||
- [`UnsafeCell::into_inner`](https://doc.rust-lang.org/stable/core/cell/struct.UnsafeCell.html#method.into_inner)
|
||||
- [`array::from_mut`](https://doc.rust-lang.org/stable/core/array/fn.from_mut.html)
|
||||
- [`char::encode_utf8`](https://doc.rust-lang.org/stable/core/primitive.char.html#method.encode_utf8)
|
||||
- [`{float}::classify`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.classify)
|
||||
- [`{float}::is_finite`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_finite)
|
||||
- [`{float}::is_infinite`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_infinite)
|
||||
- [`{float}::is_nan`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_nan)
|
||||
- [`{float}::is_normal`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_normal)
|
||||
- [`{float}::is_sign_negative`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_sign_negative)
|
||||
- [`{float}::is_sign_positive`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_sign_positive)
|
||||
- [`{float}::is_subnormal`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.is_subnormal)
|
||||
- [`{float}::from_bits`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_bits)
|
||||
- [`{float}::from_be_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_be_bytes)
|
||||
- [`{float}::from_le_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_le_bytes)
|
||||
- [`{float}::from_ne_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.from_ne_bytes)
|
||||
- [`{float}::to_bits`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_bits)
|
||||
- [`{float}::to_be_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_be_bytes)
|
||||
- [`{float}::to_le_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_le_bytes)
|
||||
- [`{float}::to_ne_bytes`](https://doc.rust-lang.org/stable/core/primitive.f64.html#method.to_ne_bytes)
|
||||
- [`mem::replace`](https://doc.rust-lang.org/stable/core/mem/fn.replace.html)
|
||||
- [`ptr::replace`](https://doc.rust-lang.org/stable/core/ptr/fn.replace.html)
|
||||
- [`ptr::slice_from_raw_parts_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.slice_from_raw_parts_mut.html)
|
||||
- [`ptr::write`](https://doc.rust-lang.org/stable/core/ptr/fn.write.html)
|
||||
- [`ptr::write_unaligned`](https://doc.rust-lang.org/stable/core/ptr/fn.write_unaligned.html)
|
||||
- [`<*const _>::copy_to`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to)
|
||||
- [`<*const _>::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to_nonoverlapping)
|
||||
- [`<*mut _>::copy_from`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_from)
|
||||
- [`<*mut _>::copy_from_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_from_nonoverlapping)
|
||||
- [`<*mut _>::copy_to`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to-1)
|
||||
- [`<*mut _>::copy_to_nonoverlapping`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.copy_to_nonoverlapping-1)
|
||||
- [`<*mut _>::write`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write)
|
||||
- [`<*mut _>::write_bytes`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write_bytes)
|
||||
- [`<*mut _>::write_unaligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.write_unaligned)
|
||||
- [`slice::from_mut`](https://doc.rust-lang.org/stable/core/slice/fn.from_mut.html)
|
||||
- [`slice::from_raw_parts_mut`](https://doc.rust-lang.org/stable/core/slice/fn.from_raw_parts_mut.html)
|
||||
- [`<[_]>::first_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.first_mut)
|
||||
- [`<[_]>::last_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.last_mut)
|
||||
- [`<[_]>::first_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.first_chunk_mut)
|
||||
- [`<[_]>::last_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.last_chunk_mut)
|
||||
- [`<[_]>::split_at_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut)
|
||||
- [`<[_]>::split_at_mut_checked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_checked)
|
||||
- [`<[_]>::split_at_mut_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_unchecked)
|
||||
- [`<[_]>::split_first_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_first_mut)
|
||||
- [`<[_]>::split_last_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_last_mut)
|
||||
- [`<[_]>::split_first_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_first_chunk_mut)
|
||||
- [`<[_]>::split_last_chunk_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_last_chunk_mut)
|
||||
- [`str::as_bytes_mut`](https://doc.rust-lang.org/stable/core/primitive.str.html#method.as_bytes_mut)
|
||||
- [`str::as_mut_ptr`](https://doc.rust-lang.org/stable/core/primitive.str.html#method.as_mut_ptr)
|
||||
- [`str::from_utf8_unchecked_mut`](https://doc.rust-lang.org/stable/core/str/fn.from_utf8_unchecked_mut.html)
|
||||
|
||||
|
||||
<a id="1.83.0-Cargo"></a>
|
||||
|
||||
Cargo
|
||||
-----
|
||||
- [Introduced a new `CARGO_MANIFEST_PATH` environment variable, similar to `CARGO_MANIFEST_DIR` but pointing directly to the manifest file.](https://github.com/rust-lang/cargo/pull/14404/)
|
||||
- [Added `package.autolib` to the manifest, allowing `[lib]` auto-discovery to be disabled.](https://github.com/rust-lang/cargo/pull/14591/)
|
||||
- [Declare support level for each crate in Cargo's Charter / crate docs.](https://github.com/rust-lang/cargo/pull/14600/)
|
||||
- [Declare new Intentional Artifacts as 'small' changes.](https://github.com/rust-lang/cargo/pull/14599/)
|
||||
|
||||
|
||||
<a id="1.83-Rustdoc"></a>
|
||||
|
||||
Rustdoc
|
||||
-------
|
||||
|
||||
- [The sidebar / hamburger menu table of contents now includes the `# headers` from the main item's doc comment](https://github.com/rust-lang/rust/pull/120736). This is similar to a third-party feature provided by the rustdoc-search-enhancements browser extension.
|
||||
|
||||
|
||||
<a id="1.83.0-Compatibility-Notes"></a>
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
- [Warn against function pointers using unsupported ABI strings.](https://github.com/rust-lang/rust/pull/128784)
|
||||
- [Check well-formedness of the source type's signature in fn pointer casts.](https://github.com/rust-lang/rust/pull/129021) This partly closes a soundness hole that comes when casting a function item to function pointer
|
||||
- [Use equality instead of subtyping when resolving type dependent paths.](https://github.com/rust-lang/rust/pull/129073)
|
||||
- Linking on macOS now correctly includes Rust's default deployment target. Due to a linker bug, you might have to pass `MACOSX_DEPLOYMENT_TARGET` or fix your `#[link]` attributes to point to the correct frameworks. See <https://github.com/rust-lang/rust/pull/129369>.
|
||||
- [Rust will now correctly raise an error for `repr(Rust)` written on non-`struct`/`enum`/`union` items, since it previous did not have any effect.](https://github.com/rust-lang/rust/pull/129422)
|
||||
- The future incompatibility lint `deprecated_cfg_attr_crate_type_name` [has been made into a hard error](https://github.com/rust-lang/rust/pull/129670). It was used to deny usage of `#![crate_type]` and `#![crate_name]` attributes in `#![cfg_attr]`, which required a hack in the compiler to be able to change the used crate type and crate name after cfg expansion.
|
||||
Users can use `--crate-type` instead of `#![cfg_attr(..., crate_type = "...")]` and `--crate-name` instead of `#![cfg_attr(..., crate_name = "...")]` when running `rustc`/`cargo rustc` on the command line.
|
||||
Use of those two attributes outside of `#![cfg_attr]` continue to be fully supported.
|
||||
- Until now, paths into the sysroot were always prefixed with `/rustc/$hash` in diagnostics, codegen, backtrace, e.g.
|
||||
```
|
||||
thread 'main' panicked at 'hello world', map-panic.rs:2:50
|
||||
stack backtrace:
|
||||
0: std::panicking::begin_panic
|
||||
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:616:12
|
||||
1: map_panic::main::{{closure}}
|
||||
at ./map-panic.rs:2:50
|
||||
2: core::option::Option<T>::map
|
||||
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/option.rs:929:29
|
||||
3: map_panic::main
|
||||
at ./map-panic.rs:2:30
|
||||
4: core::ops::function::FnOnce::call_once
|
||||
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/ops/function.rs:248:5
|
||||
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
||||
```
|
||||
[RFC 3127 said](https://rust-lang.github.io/rfcs/3127-trim-paths.html#changing-handling-of-sysroot-path-in-rustc)
|
||||
> We want to change this behaviour such that, when `rust-src` source files can be discovered, the virtual path is discarded and therefore the local path will be embedded, unless there is a `--remap-path-prefix` that causes this local path to be remapped in the usual way.
|
||||
|
||||
[#129687](https://github.com/rust-lang/rust/pull/129687) implements this behaviour, when `rust-src` is present at compile time, `rustc` replaces `/rustc/$hash` with a real path into the local `rust-src` component with best effort.
|
||||
To sanitize this, users must explicitly supply `--remap-path-prefix=<path to rust-src>=foo` or not have the `rust-src` component installed.
|
||||
- The allow-by-default `missing_docs` lint used to disable itself when invoked through `rustc --test`/`cargo test`, resulting in `#[expect(missing_docs)]` emitting false positives due to the expectation being wrongly unfulfilled. This behavior [has now been removed](https://github.com/rust-lang/rust/pull/130025), which allows `#[expect(missing_docs)]` to be fulfilled in all scenarios, but will also report new `missing_docs` diagnostics for publicly reachable `#[cfg(test)]` items, [integration test](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#integration-tests) crate-level documentation, and publicly reachable items in integration tests.
|
||||
- [The `armv8r-none-eabihf` target now uses the Armv8-R required set of floating-point features.](https://github.com/rust-lang/rust/pull/130295)
|
||||
- [Fix a soundness bug where rustc wouldn't detect unconstrained higher-ranked lifetimes in a `dyn Trait`'s associated types that occur due to supertraits.](https://github.com/rust-lang/rust/pull/130367)
|
||||
- [Update the minimum external LLVM version to 18.](https://github.com/rust-lang/rust/pull/130487)
|
||||
- [Remove `aarch64-fuchsia` and `x86_64-fuchsia` target aliases in favor of `aarch64-unknown-fuchsia` and `x86_64-unknown-fuchsia` respectively.](https://github.com/rust-lang/rust/pull/130657)
|
||||
- [The ABI-level exception class of a Rust panic is now encoded with native-endian bytes, so it is legible in hex dumps.](https://github.com/rust-lang/rust/pull/130897)
|
||||
- [Visual Studio 2013 is no longer supported for MSVC targets.](https://github.com/rust-lang/rust/pull/131070)
|
||||
- [The sysroot no longer contains the `std` dynamic library in its top-level `lib/` dir.](https://github.com/rust-lang/rust/pull/131188)
|
||||
|
||||
|
||||
Version 1.82.0 (2024-10-17)
|
||||
==========================
|
||||
|
||||
|
|
@ -125,7 +357,7 @@ 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::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)
|
||||
- [`{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>
|
||||
|
|
|
|||
|
|
@ -209,6 +209,24 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_single_vector_element<C>(self, cx: &C, expected_size: Size) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
match self.backend_repr {
|
||||
BackendRepr::Vector { .. } => self.size == expected_size,
|
||||
BackendRepr::Memory { .. } => {
|
||||
if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 {
|
||||
self.field(cx, 0).is_single_vector_element(cx, expected_size)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_adt<C>(self) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
|
|
|
|||
|
|
@ -457,7 +457,7 @@ impl MetaItemKind {
|
|||
tokens: &mut impl Iterator<Item = &'a TokenTree>,
|
||||
) -> Option<MetaItemKind> {
|
||||
match tokens.next() {
|
||||
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
|
||||
Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) => {
|
||||
MetaItemKind::name_value_from_tokens(&mut inner_tokens.trees())
|
||||
}
|
||||
Some(TokenTree::Token(token, _)) => {
|
||||
|
|
@ -605,7 +605,7 @@ impl MetaItemInner {
|
|||
tokens.next();
|
||||
return Some(MetaItemInner::Lit(lit));
|
||||
}
|
||||
Some(TokenTree::Delimited(.., Delimiter::Invisible, inner_tokens)) => {
|
||||
Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) => {
|
||||
tokens.next();
|
||||
return MetaItemInner::from_tokens(&mut inner_tokens.trees().peekable());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,8 +104,16 @@ pub trait MutVisitor: Sized {
|
|||
walk_use_tree(self, use_tree);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) {
|
||||
walk_item(self, ni);
|
||||
}
|
||||
|
||||
fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
|
||||
walk_flat_map_item(self, ni)
|
||||
walk_flat_map_foreign_item(self, ni)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &mut P<Item>) {
|
||||
walk_item(self, i);
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
|
|
@ -116,10 +124,18 @@ pub trait MutVisitor: Sized {
|
|||
walk_fn_header(self, header);
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, fd: &mut FieldDef) {
|
||||
walk_field_def(self, fd);
|
||||
}
|
||||
|
||||
fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
|
||||
walk_flat_map_field_def(self, fd)
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) {
|
||||
walk_assoc_item(self, i, ctxt)
|
||||
}
|
||||
|
||||
fn flat_map_assoc_item(
|
||||
&mut self,
|
||||
i: P<AssocItem>,
|
||||
|
|
@ -153,6 +169,10 @@ pub trait MutVisitor: Sized {
|
|||
walk_flat_map_stmt(self, s)
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, arm: &mut Arm) {
|
||||
walk_arm(self, arm);
|
||||
}
|
||||
|
||||
fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
walk_flat_map_arm(self, arm)
|
||||
}
|
||||
|
|
@ -199,6 +219,10 @@ pub trait MutVisitor: Sized {
|
|||
walk_foreign_mod(self, nm);
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &mut Variant) {
|
||||
walk_variant(self, v);
|
||||
}
|
||||
|
||||
fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
|
||||
walk_flat_map_variant(self, v)
|
||||
}
|
||||
|
|
@ -251,6 +275,10 @@ pub trait MutVisitor: Sized {
|
|||
walk_attribute(self, at);
|
||||
}
|
||||
|
||||
fn visit_param(&mut self, param: &mut Param) {
|
||||
walk_param(self, param);
|
||||
}
|
||||
|
||||
fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
|
||||
walk_flat_map_param(self, param)
|
||||
}
|
||||
|
|
@ -271,6 +299,10 @@ pub trait MutVisitor: Sized {
|
|||
walk_variant_data(self, vdata);
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, param: &mut GenericParam) {
|
||||
walk_generic_param(self, param)
|
||||
}
|
||||
|
||||
fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
|
||||
walk_flat_map_generic_param(self, param)
|
||||
}
|
||||
|
|
@ -287,6 +319,10 @@ pub trait MutVisitor: Sized {
|
|||
walk_mt(self, mt);
|
||||
}
|
||||
|
||||
fn visit_expr_field(&mut self, f: &mut ExprField) {
|
||||
walk_expr_field(self, f);
|
||||
}
|
||||
|
||||
fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
|
||||
walk_flat_map_expr_field(self, f)
|
||||
}
|
||||
|
|
@ -311,6 +347,10 @@ pub trait MutVisitor: Sized {
|
|||
// Do nothing.
|
||||
}
|
||||
|
||||
fn visit_pat_field(&mut self, fp: &mut PatField) {
|
||||
walk_pat_field(self, fp)
|
||||
}
|
||||
|
||||
fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
|
||||
walk_flat_map_pat_field(self, fp)
|
||||
}
|
||||
|
|
@ -429,16 +469,20 @@ pub fn visit_delim_span<T: MutVisitor>(vis: &mut T, DelimSpan { open, close }: &
|
|||
vis.visit_span(close);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fp: PatField,
|
||||
) -> SmallVec<[PatField; 1]> {
|
||||
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp;
|
||||
pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
|
||||
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fp: PatField,
|
||||
) -> SmallVec<[PatField; 1]> {
|
||||
vis.visit_pat_field(&mut fp);
|
||||
smallvec![fp]
|
||||
}
|
||||
|
||||
|
|
@ -459,14 +503,18 @@ fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
|
|||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
|
||||
pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
|
||||
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_pat(pat);
|
||||
visit_opt(guard, |guard| vis.visit_expr(guard));
|
||||
visit_opt(body, |body| vis.visit_expr(body));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
vis.visit_arm(&mut arm);
|
||||
smallvec![arm]
|
||||
}
|
||||
|
||||
|
|
@ -543,11 +591,8 @@ fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
|||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
visitor: &mut T,
|
||||
mut variant: Variant,
|
||||
) -> SmallVec<[Variant; 1]> {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
|
||||
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
|
|
@ -555,6 +600,13 @@ pub fn walk_flat_map_variant<T: MutVisitor>(
|
|||
visitor.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut variant: Variant,
|
||||
) -> SmallVec<[Variant; 1]> {
|
||||
vis.visit_variant(&mut variant);
|
||||
smallvec![variant]
|
||||
}
|
||||
|
||||
|
|
@ -685,13 +737,17 @@ fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
|
|||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
|
||||
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
|
||||
pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
|
||||
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
|
||||
vis.visit_param(&mut param);
|
||||
smallvec![param]
|
||||
}
|
||||
|
||||
|
|
@ -950,11 +1006,8 @@ fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCaptu
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut param: GenericParam,
|
||||
) -> SmallVec<[GenericParam; 1]> {
|
||||
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
|
||||
pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
|
||||
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
|
|
@ -972,6 +1025,13 @@ pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
|||
if let Some(colon_span) = colon_span {
|
||||
vis.visit_span(colon_span);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut param: GenericParam,
|
||||
) -> SmallVec<[GenericParam; 1]> {
|
||||
vis.visit_generic_param(&mut param);
|
||||
smallvec![param]
|
||||
}
|
||||
|
||||
|
|
@ -1054,30 +1114,38 @@ fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
|||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_field_def<T: MutVisitor>(
|
||||
visitor: &mut T,
|
||||
mut fd: FieldDef,
|
||||
) -> SmallVec<[FieldDef; 1]> {
|
||||
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
|
||||
pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
|
||||
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd;
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
visit_opt(ident, |ident| visitor.visit_ident(ident));
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_field_def<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fd: FieldDef,
|
||||
) -> SmallVec<[FieldDef; 1]> {
|
||||
vis.visit_field_def(&mut fd);
|
||||
smallvec![fd]
|
||||
}
|
||||
|
||||
pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
|
||||
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_expr_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut f: ExprField,
|
||||
) -> SmallVec<[ExprField; 1]> {
|
||||
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(span);
|
||||
vis.visit_expr_field(&mut f);
|
||||
smallvec![f]
|
||||
}
|
||||
|
||||
|
|
@ -1331,18 +1399,19 @@ pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
|
|||
vis.visit_span(inject_use_span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item<K: WalkItemKind<Ctxt = ()>>(
|
||||
visitor: &mut impl MutVisitor,
|
||||
item: P<Item<K>>,
|
||||
) -> SmallVec<[P<Item<K>>; 1]> {
|
||||
walk_flat_map_assoc_item(visitor, item, ())
|
||||
pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P<Item<impl WalkItemKind<Ctxt = ()>>>) {
|
||||
walk_item_ctxt(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
|
||||
pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, ctxt: AssocCtxt) {
|
||||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<K: WalkItemKind>(
|
||||
visitor: &mut impl MutVisitor,
|
||||
mut item: P<Item<K>>,
|
||||
item: &mut P<Item<K>>,
|
||||
ctxt: K::Ctxt,
|
||||
) -> SmallVec<[P<Item<K>>; 1]> {
|
||||
) {
|
||||
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
|
|
@ -1351,6 +1420,27 @@ pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
|
|||
kind.walk(*span, *id, ident, vis, ctxt, visitor);
|
||||
visit_lazy_tts(visitor, tokens);
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
vis.visit_item(&mut item);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_foreign_item(
|
||||
vis: &mut impl MutVisitor,
|
||||
mut item: P<ForeignItem>,
|
||||
) -> SmallVec<[P<ForeignItem>; 1]> {
|
||||
vis.visit_foreign_item(&mut item);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_assoc_item(
|
||||
vis: &mut impl MutVisitor,
|
||||
mut item: P<AssocItem>,
|
||||
ctxt: AssocCtxt,
|
||||
) -> SmallVec<[P<AssocItem>; 1]> {
|
||||
vis.visit_assoc_item(&mut item, ctxt);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,11 +42,86 @@ pub enum BinOpToken {
|
|||
Shr,
|
||||
}
|
||||
|
||||
// This type must not implement `Hash` due to the unusual `PartialEq` impl below.
|
||||
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum InvisibleOrigin {
|
||||
// From the expansion of a metavariable in a declarative macro.
|
||||
MetaVar(MetaVarKind),
|
||||
|
||||
// Converted from `proc_macro::Delimiter` in
|
||||
// `proc_macro::Delimiter::to_internal`, i.e. returned by a proc macro.
|
||||
ProcMacro,
|
||||
|
||||
// Converted from `TokenKind::Interpolated` in
|
||||
// `TokenStream::flatten_token`. Treated similarly to `ProcMacro`.
|
||||
FlattenToken,
|
||||
}
|
||||
|
||||
impl PartialEq for InvisibleOrigin {
|
||||
#[inline]
|
||||
fn eq(&self, _other: &InvisibleOrigin) -> bool {
|
||||
// When we had AST-based nonterminals we couldn't compare them, and the
|
||||
// old `Nonterminal` type had an `eq` that always returned false,
|
||||
// resulting in this restriction:
|
||||
// https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
|
||||
// This `eq` emulates that behaviour. We could consider lifting this
|
||||
// restriction now but there are still cases involving invisible
|
||||
// delimiters that make it harder than it first appears.
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Annoyingly similar to `NonterminalKind`, but the slight differences are important.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
|
||||
pub enum MetaVarKind {
|
||||
Item,
|
||||
Block,
|
||||
Stmt,
|
||||
Pat(NtPatKind),
|
||||
Expr {
|
||||
kind: NtExprKind,
|
||||
// This field is needed for `Token::can_begin_literal_maybe_minus`.
|
||||
can_begin_literal_maybe_minus: bool,
|
||||
// This field is needed for `Token::can_begin_string_literal`.
|
||||
can_begin_string_literal: bool,
|
||||
},
|
||||
Ty,
|
||||
Ident,
|
||||
Lifetime,
|
||||
Literal,
|
||||
Meta,
|
||||
Path,
|
||||
Vis,
|
||||
TT,
|
||||
}
|
||||
|
||||
impl fmt::Display for MetaVarKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let sym = match self {
|
||||
MetaVarKind::Item => sym::item,
|
||||
MetaVarKind::Block => sym::block,
|
||||
MetaVarKind::Stmt => sym::stmt,
|
||||
MetaVarKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
|
||||
MetaVarKind::Pat(PatParam { inferred: false }) => sym::pat_param,
|
||||
MetaVarKind::Expr { kind: Expr2021 { inferred: true } | Expr, .. } => sym::expr,
|
||||
MetaVarKind::Expr { kind: Expr2021 { inferred: false }, .. } => sym::expr_2021,
|
||||
MetaVarKind::Ty => sym::ty,
|
||||
MetaVarKind::Ident => sym::ident,
|
||||
MetaVarKind::Lifetime => sym::lifetime,
|
||||
MetaVarKind::Literal => sym::literal,
|
||||
MetaVarKind::Meta => sym::meta,
|
||||
MetaVarKind::Path => sym::path,
|
||||
MetaVarKind::Vis => sym::vis,
|
||||
MetaVarKind::TT => sym::tt,
|
||||
};
|
||||
write!(f, "{sym}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how a sequence of token trees is delimited.
|
||||
/// Cannot use `proc_macro::Delimiter` directly because this
|
||||
/// structure should implement some additional traits.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Encodable, Decodable, Hash, HashStable_Generic)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum Delimiter {
|
||||
/// `( ... )`
|
||||
Parenthesis,
|
||||
|
|
@ -59,7 +134,34 @@ pub enum Delimiter {
|
|||
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
|
||||
/// `$var * 3` where `$var` is `1 + 2`.
|
||||
/// Invisible delimiters might not survive roundtrip of a token stream through a string.
|
||||
Invisible,
|
||||
Invisible(InvisibleOrigin),
|
||||
}
|
||||
|
||||
impl Delimiter {
|
||||
// Should the parser skip these delimiters? Only happens for certain kinds
|
||||
// of invisible delimiters. Ideally this function will eventually disappear
|
||||
// and no invisible delimiters will be skipped.
|
||||
#[inline]
|
||||
pub fn skip(&self) -> bool {
|
||||
match self {
|
||||
Delimiter::Parenthesis | Delimiter::Bracket | Delimiter::Brace => false,
|
||||
Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) => false,
|
||||
Delimiter::Invisible(InvisibleOrigin::FlattenToken | InvisibleOrigin::ProcMacro) => {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This exists because `InvisibleOrigin`s should be compared. It is only used for assertions.
|
||||
pub fn eq_ignoring_invisible_origin(&self, other: &Delimiter) -> bool {
|
||||
match (self, other) {
|
||||
(Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
|
||||
(Delimiter::Brace, Delimiter::Brace) => true,
|
||||
(Delimiter::Bracket, Delimiter::Bracket) => true,
|
||||
(Delimiter::Invisible(_), Delimiter::Invisible(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that the suffix is *not* considered when deciding the `LitKind` in this
|
||||
|
|
@ -496,10 +598,11 @@ impl Token {
|
|||
/// **NB**: Take care when modifying this function, since it will change
|
||||
/// the stable set of tokens that are allowed to match an expr nonterminal.
|
||||
pub fn can_begin_expr(&self) -> bool {
|
||||
use Delimiter::*;
|
||||
match self.uninterpolate().kind {
|
||||
Ident(name, is_raw) =>
|
||||
ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
|
||||
OpenDelim(..) | // tuple, array or block
|
||||
OpenDelim(Parenthesis | Brace | Bracket) | // tuple, array or block
|
||||
Literal(..) | // literal
|
||||
Not | // operator not
|
||||
BinOp(Minus) | // unary minus
|
||||
|
|
@ -510,7 +613,7 @@ impl Token {
|
|||
// DotDotDot is no longer supported, but we need some way to display the error
|
||||
DotDot | DotDotDot | DotDotEq | // range notation
|
||||
Lt | BinOp(Shl) | // associated path
|
||||
PathSep | // global path
|
||||
PathSep | // global path
|
||||
Lifetime(..) | // labeled loop
|
||||
Pound => true, // expression attributes
|
||||
Interpolated(ref nt) =>
|
||||
|
|
@ -520,6 +623,12 @@ impl Token {
|
|||
NtLiteral(..) |
|
||||
NtPath(..)
|
||||
),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Block |
|
||||
MetaVarKind::Expr { .. } |
|
||||
MetaVarKind::Literal |
|
||||
MetaVarKind::Path
|
||||
))) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -553,6 +662,14 @@ impl Token {
|
|||
| NtPath(..)
|
||||
| NtTy(..)
|
||||
),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Expr { .. } |
|
||||
MetaVarKind::Literal |
|
||||
MetaVarKind::Meta |
|
||||
MetaVarKind::Pat(_) |
|
||||
MetaVarKind::Path |
|
||||
MetaVarKind::Ty
|
||||
))) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -573,6 +690,10 @@ impl Token {
|
|||
Lt | BinOp(Shl) | // associated path
|
||||
PathSep => true, // global path
|
||||
Interpolated(ref nt) => matches!(&**nt, NtTy(..) | NtPath(..)),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Ty |
|
||||
MetaVarKind::Path
|
||||
))) => true,
|
||||
// For anonymous structs or unions, which only appear in specific positions
|
||||
// (type of struct fields or union fields), we don't consider them as regular types
|
||||
_ => false,
|
||||
|
|
@ -585,6 +706,9 @@ impl Token {
|
|||
OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true,
|
||||
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
|
||||
Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
|
||||
MetaVarKind::Expr { .. } | MetaVarKind::Block | MetaVarKind::Literal,
|
||||
))) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -641,6 +765,13 @@ impl Token {
|
|||
},
|
||||
_ => false,
|
||||
},
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
|
||||
MetaVarKind::Literal => true,
|
||||
MetaVarKind::Expr { can_begin_literal_maybe_minus, .. } => {
|
||||
can_begin_literal_maybe_minus
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -656,6 +787,11 @@ impl Token {
|
|||
},
|
||||
_ => false,
|
||||
},
|
||||
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
|
||||
MetaVarKind::Literal => true,
|
||||
MetaVarKind::Expr { can_begin_string_literal, .. } => can_begin_string_literal,
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -896,7 +1032,7 @@ impl PartialEq<TokenKind> for Token {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
|
||||
pub enum NtPatKind {
|
||||
// Matches or-patterns. Was written using `pat` in edition 2021 or later.
|
||||
PatWithOr,
|
||||
|
|
@ -906,7 +1042,7 @@ pub enum NtPatKind {
|
|||
PatParam { inferred: bool },
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
|
||||
pub enum NtExprKind {
|
||||
// Matches expressions using the post-edition 2024. Was written using
|
||||
// `expr` in edition 2024 or later.
|
||||
|
|
@ -933,7 +1069,7 @@ pub enum Nonterminal {
|
|||
NtVis(P<ast::Visibility>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
|
||||
pub enum NonterminalKind {
|
||||
Item,
|
||||
Block,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym};
|
|||
|
||||
use crate::ast::{AttrStyle, StmtKind};
|
||||
use crate::ast_traits::{HasAttrs, HasTokens};
|
||||
use crate::token::{self, Delimiter, Nonterminal, Token, TokenKind};
|
||||
use crate::token::{self, Delimiter, InvisibleOrigin, Nonterminal, Token, TokenKind};
|
||||
use crate::{AttrVec, Attribute};
|
||||
|
||||
/// Part of a `TokenStream`.
|
||||
|
|
@ -484,13 +484,13 @@ impl TokenStream {
|
|||
token::NtLifetime(ident, is_raw) => TokenTree::Delimited(
|
||||
DelimSpan::from_single(token.span),
|
||||
DelimSpacing::new(Spacing::JointHidden, spacing),
|
||||
Delimiter::Invisible,
|
||||
Delimiter::Invisible(InvisibleOrigin::FlattenToken),
|
||||
TokenStream::token_alone(token::Lifetime(ident.name, is_raw), ident.span),
|
||||
),
|
||||
token::Interpolated(ref nt) => TokenTree::Delimited(
|
||||
DelimSpan::from_single(token.span),
|
||||
DelimSpacing::new(Spacing::JointHidden, spacing),
|
||||
Delimiter::Invisible,
|
||||
Delimiter::Invisible(InvisibleOrigin::FlattenToken),
|
||||
TokenStream::from_nonterminal_ast(&nt).flattened(),
|
||||
),
|
||||
_ => TokenTree::Token(token.clone(), spacing),
|
||||
|
|
|
|||
|
|
@ -463,13 +463,6 @@ impl WalkItemKind for ItemKind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
|
||||
) -> V::Result {
|
||||
walk_assoc_item(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_enum_def<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
EnumDef { variants }: &'a EnumDef,
|
||||
|
|
@ -931,7 +924,22 @@ impl WalkItemKind for AssocItemKind {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>(
|
||||
pub fn walk_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
|
||||
) -> V::Result {
|
||||
walk_item_ctxt(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_assoc_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a AssocItem,
|
||||
ctxt: AssocCtxt,
|
||||
) -> V::Result {
|
||||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<K>,
|
||||
ctxt: K::Ctxt,
|
||||
|
|
|
|||
|
|
@ -942,9 +942,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
|||
token::CloseDelim(Delimiter::Bracket) => "]".into(),
|
||||
token::OpenDelim(Delimiter::Brace) => "{".into(),
|
||||
token::CloseDelim(Delimiter::Brace) => "}".into(),
|
||||
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible) => {
|
||||
"".into()
|
||||
}
|
||||
token::OpenDelim(Delimiter::Invisible(_))
|
||||
| token::CloseDelim(Delimiter::Invisible(_)) => "".into(),
|
||||
token::Pound => "#".into(),
|
||||
token::Dollar => "$".into(),
|
||||
token::Question => "?".into(),
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ impl MutVisitor for CfgEval<'_> {
|
|||
foreign_item: P<ast::ForeignItem>,
|
||||
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
||||
let foreign_item = configure!(self, foreign_item);
|
||||
mut_visit::walk_flat_map_item(self, foreign_item)
|
||||
mut_visit::walk_flat_map_foreign_item(self, foreign_item)
|
||||
}
|
||||
|
||||
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Code that generates a test runner to run all the tests in a crate
|
||||
|
||||
use std::{iter, mem};
|
||||
use std::mem;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::entry::EntryPointType;
|
||||
|
|
@ -19,7 +19,7 @@ use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
|
|||
use rustc_span::symbol::{Ident, Symbol, sym};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use smallvec::smallvec;
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
use tracing::debug;
|
||||
|
||||
|
|
@ -129,8 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
|||
c.items.push(mk_main(&mut self.cx));
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, mut i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
let item = &mut *i;
|
||||
fn visit_item(&mut self, item: &mut P<ast::Item>) {
|
||||
let item = &mut **item;
|
||||
|
||||
if let Some(name) = get_test_name(&item) {
|
||||
debug!("this is a test item");
|
||||
|
||||
|
|
@ -158,7 +159,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
|||
// But in those cases, we emit a lint to warn the user of these missing tests.
|
||||
walk_item(&mut InnerItemLinter { sess: self.cx.ext_cx.sess }, &item);
|
||||
}
|
||||
smallvec![i]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,40 +198,30 @@ struct EntryPointCleaner<'a> {
|
|||
}
|
||||
|
||||
impl<'a> MutVisitor for EntryPointCleaner<'a> {
|
||||
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
fn visit_item(&mut self, item: &mut P<ast::Item>) {
|
||||
self.depth += 1;
|
||||
let item = walk_flat_map_item(self, i).expect_one("noop did something");
|
||||
ast::mut_visit::walk_item(self, item);
|
||||
self.depth -= 1;
|
||||
|
||||
// Remove any #[rustc_main] or #[start] from the AST so it doesn't
|
||||
// clash with the one we're going to add, but mark it as
|
||||
// #[allow(dead_code)] to avoid printing warnings.
|
||||
let item = match entry_point_type(&item, self.depth == 0) {
|
||||
match entry_point_type(&item, self.depth == 0) {
|
||||
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
|
||||
item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| {
|
||||
let allow_dead_code = attr::mk_attr_nested_word(
|
||||
&self.sess.psess.attr_id_generator,
|
||||
ast::AttrStyle::Outer,
|
||||
ast::Safety::Default,
|
||||
sym::allow,
|
||||
sym::dead_code,
|
||||
self.def_site,
|
||||
);
|
||||
let attrs = attrs
|
||||
.into_iter()
|
||||
.filter(|attr| {
|
||||
!attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)
|
||||
})
|
||||
.chain(iter::once(allow_dead_code))
|
||||
.collect();
|
||||
|
||||
ast::Item { id, ident, attrs, kind, vis, span, tokens }
|
||||
})
|
||||
let allow_dead_code = attr::mk_attr_nested_word(
|
||||
&self.sess.psess.attr_id_generator,
|
||||
ast::AttrStyle::Outer,
|
||||
ast::Safety::Default,
|
||||
sym::allow,
|
||||
sym::dead_code,
|
||||
self.def_site,
|
||||
);
|
||||
item.attrs
|
||||
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
|
||||
item.attrs.push(allow_dead_code);
|
||||
}
|
||||
EntryPointType::None | EntryPointType::OtherMain => item,
|
||||
EntryPointType::None | EntryPointType::OtherMain => {}
|
||||
};
|
||||
|
||||
smallvec![item]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +282,7 @@ fn generate_test_harness(
|
|||
/// Most of the Ident have the usual def-site hygiene for the AST pass. The
|
||||
/// exception is the `test_const`s. These have a syntax context that has two
|
||||
/// opaque marks: one from the expansion of `test` or `test_case`, and one
|
||||
/// generated in `TestHarnessGenerator::flat_map_item`. When resolving this
|
||||
/// generated in `TestHarnessGenerator::visit_item`. When resolving this
|
||||
/// identifier after failing to find a matching identifier in the root module
|
||||
/// we remove the outer mark, and try resolving at its def-site, which will
|
||||
/// then resolve to `test_const`.
|
||||
|
|
|
|||
|
|
@ -777,6 +777,16 @@ fn link_natively(
|
|||
info!("preparing {:?} to {:?}", crate_type, out_filename);
|
||||
let (linker_path, flavor) = linker_and_flavor(sess);
|
||||
let self_contained_components = self_contained_components(sess, crate_type);
|
||||
|
||||
// On AIX, we ship all libraries as .a big_af archive
|
||||
// the expected format is lib<name>.a(libname.so) for the actual
|
||||
// dynamic library. So we link to a temporary .so file to be archived
|
||||
// at the final out_filename location
|
||||
let should_archive = crate_type != CrateType::Executable && sess.target.is_like_aix;
|
||||
let archive_member =
|
||||
should_archive.then(|| tmpdir.join(out_filename.file_name().unwrap()).with_extension("so"));
|
||||
let temp_filename = archive_member.as_deref().unwrap_or(out_filename);
|
||||
|
||||
let mut cmd = linker_with_args(
|
||||
&linker_path,
|
||||
flavor,
|
||||
|
|
@ -784,7 +794,7 @@ fn link_natively(
|
|||
archive_builder_builder,
|
||||
crate_type,
|
||||
tmpdir,
|
||||
out_filename,
|
||||
temp_filename,
|
||||
codegen_results,
|
||||
self_contained_components,
|
||||
)?;
|
||||
|
|
@ -1158,6 +1168,12 @@ fn link_natively(
|
|||
}
|
||||
}
|
||||
|
||||
if should_archive {
|
||||
let mut ab = archive_builder_builder.new_archive_builder(sess);
|
||||
ab.add_file(temp_filename);
|
||||
ab.build(out_filename);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::fs::File;
|
|||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use itertools::Itertools;
|
||||
use object::write::{self, StandardSegment, Symbol, SymbolSection};
|
||||
use object::{
|
||||
Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, ObjectSymbol,
|
||||
|
|
@ -21,6 +22,7 @@ use rustc_middle::bug;
|
|||
use rustc_session::Session;
|
||||
use rustc_span::sym;
|
||||
use rustc_target::spec::{RelocModel, Target, ef_avr_arch};
|
||||
use tracing::debug;
|
||||
|
||||
use super::apple;
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ fn load_metadata_with(
|
|||
|
||||
impl MetadataLoader for DefaultMetadataLoader {
|
||||
fn get_rlib_metadata(&self, target: &Target, path: &Path) -> Result<OwnedSlice, String> {
|
||||
debug!("getting rlib metadata for {}", path.display());
|
||||
load_metadata_with(path, |data| {
|
||||
let archive = object::read::archive::ArchiveFile::parse(&*data)
|
||||
.map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?;
|
||||
|
|
@ -77,8 +80,26 @@ impl MetadataLoader for DefaultMetadataLoader {
|
|||
}
|
||||
|
||||
fn get_dylib_metadata(&self, target: &Target, path: &Path) -> Result<OwnedSlice, String> {
|
||||
debug!("getting dylib metadata for {}", path.display());
|
||||
if target.is_like_aix {
|
||||
load_metadata_with(path, |data| get_metadata_xcoff(path, data))
|
||||
load_metadata_with(path, |data| {
|
||||
let archive = object::read::archive::ArchiveFile::parse(&*data).map_err(|e| {
|
||||
format!("failed to parse aix dylib '{}': {}", path.display(), e)
|
||||
})?;
|
||||
|
||||
match archive.members().exactly_one() {
|
||||
Ok(lib) => {
|
||||
let lib = lib.map_err(|e| {
|
||||
format!("failed to parse aix dylib '{}': {}", path.display(), e)
|
||||
})?;
|
||||
let data = lib.data(data).map_err(|e| {
|
||||
format!("failed to parse aix dylib '{}': {}", path.display(), e)
|
||||
})?;
|
||||
get_metadata_xcoff(path, data)
|
||||
}
|
||||
Err(e) => Err(format!("failed to parse aix dylib '{}': {}", path.display(), e)),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,3 +23,5 @@ driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc ver
|
|||
driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`
|
||||
|
||||
driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file
|
||||
|
||||
driver_impl_unstable_feature_usage = cannot dump feature usage metrics: {$error}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#![feature(panic_update_hook)]
|
||||
#![feature(result_flattening)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(try_blocks)]
|
||||
#![warn(unreachable_pub)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ use rustc_interface::{Linker, Queries, interface, passes};
|
|||
use rustc_lint::unerased_lint_store;
|
||||
use rustc_metadata::creader::MetadataLoader;
|
||||
use rustc_metadata::locator;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
||||
use rustc_session::config::{
|
||||
CG_OPTIONS, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, Z_OPTIONS,
|
||||
|
|
@ -102,7 +104,7 @@ mod signal_handler {
|
|||
|
||||
use crate::session_diagnostics::{
|
||||
RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch,
|
||||
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead,
|
||||
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage,
|
||||
};
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
|
@ -430,6 +432,10 @@ fn run_compiler(
|
|||
// Make sure name resolution and macro expansion is run.
|
||||
queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering());
|
||||
|
||||
if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
|
||||
queries.global_ctxt()?.enter(|tcxt| dump_feature_usage_metrics(tcxt, metrics_dir));
|
||||
}
|
||||
|
||||
if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
|
||||
return early_exit();
|
||||
}
|
||||
|
|
@ -474,6 +480,23 @@ fn run_compiler(
|
|||
})
|
||||
}
|
||||
|
||||
fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &PathBuf) {
|
||||
let output_filenames = tcxt.output_filenames(());
|
||||
let mut metrics_file_name = std::ffi::OsString::from("unstable_feature_usage_metrics-");
|
||||
let mut metrics_path = output_filenames.with_directory_and_extension(metrics_dir, "json");
|
||||
let metrics_file_stem =
|
||||
metrics_path.file_name().expect("there should be a valid default output filename");
|
||||
metrics_file_name.push(metrics_file_stem);
|
||||
metrics_path.pop();
|
||||
metrics_path.push(metrics_file_name);
|
||||
if let Err(error) = tcxt.features().dump_feature_usage_metrics(metrics_path) {
|
||||
// FIXME(yaahc): once metrics can be enabled by default we will want "failure to emit
|
||||
// default metrics" to only produce a warning when metrics are enabled by default and emit
|
||||
// an error only when the user manually enables metrics
|
||||
tcxt.dcx().emit_err(UnstableFeatureUsage { error });
|
||||
}
|
||||
}
|
||||
|
||||
// Extract output directory and file from matches.
|
||||
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileName>) {
|
||||
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
|
||||
|
|
@ -564,71 +587,63 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
|
|||
}
|
||||
}
|
||||
|
||||
/// If color is always or auto, print formatted & colorized markdown. If color is never or
|
||||
/// if formatted printing fails, print the raw text.
|
||||
/// If `color` is `always` or `auto`, try to print pretty (formatted & colorized) markdown. If
|
||||
/// that fails or `color` is `never`, print the raw markdown.
|
||||
///
|
||||
/// Prefers a pager, falls back standard print
|
||||
/// Uses a pager if possible, falls back to stdout.
|
||||
fn show_md_content_with_pager(content: &str, color: ColorConfig) {
|
||||
let mut fallback_to_println = false;
|
||||
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
|
||||
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
|
||||
});
|
||||
|
||||
let mut cmd = Command::new(&pager_name);
|
||||
// FIXME: find if other pagers accept color options
|
||||
let mut print_formatted = if pager_name == "less" {
|
||||
cmd.arg("-R");
|
||||
true
|
||||
} else {
|
||||
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
|
||||
if pager_name == "less" {
|
||||
cmd.arg("-R"); // allows color escape sequences
|
||||
}
|
||||
|
||||
let pretty_on_pager = match color {
|
||||
ColorConfig::Auto => {
|
||||
// Add other pagers that accept color escape sequences here.
|
||||
["less", "bat", "batcat", "delta"].iter().any(|v| *v == pager_name)
|
||||
}
|
||||
ColorConfig::Always => true,
|
||||
ColorConfig::Never => false,
|
||||
};
|
||||
|
||||
if color == ColorConfig::Never {
|
||||
print_formatted = false;
|
||||
} else if color == ColorConfig::Always {
|
||||
print_formatted = true;
|
||||
}
|
||||
// Try to prettify the raw markdown text. The result can be used by the pager or on stdout.
|
||||
let pretty_data = {
|
||||
let mdstream = markdown::MdStream::parse_str(content);
|
||||
let bufwtr = markdown::create_stdout_bufwtr();
|
||||
let mut mdbuf = bufwtr.buffer();
|
||||
if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None }
|
||||
};
|
||||
|
||||
let mdstream = markdown::MdStream::parse_str(content);
|
||||
let bufwtr = markdown::create_stdout_bufwtr();
|
||||
let mut mdbuf = bufwtr.buffer();
|
||||
if mdstream.write_termcolor_buf(&mut mdbuf).is_err() {
|
||||
print_formatted = false;
|
||||
}
|
||||
// Try to print via the pager, pretty output if possible.
|
||||
let pager_res: Option<()> = try {
|
||||
let mut pager = cmd.stdin(Stdio::piped()).spawn().ok()?;
|
||||
|
||||
if let Ok(mut pager) = cmd.stdin(Stdio::piped()).spawn() {
|
||||
if let Some(pipe) = pager.stdin.as_mut() {
|
||||
let res = if print_formatted {
|
||||
pipe.write_all(mdbuf.as_slice())
|
||||
} else {
|
||||
pipe.write_all(content.as_bytes())
|
||||
};
|
||||
|
||||
if res.is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
}
|
||||
|
||||
if pager.wait().is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
} else {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
|
||||
// If pager fails for whatever reason, we should still print the content
|
||||
// to standard output
|
||||
if fallback_to_println {
|
||||
let fmt_success = match color {
|
||||
ColorConfig::Auto => io::stdout().is_terminal() && bufwtr.print(&mdbuf).is_ok(),
|
||||
ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(),
|
||||
ColorConfig::Never => false,
|
||||
let pager_stdin = pager.stdin.as_mut()?;
|
||||
if pretty_on_pager && let Some((_, mdbuf)) = &pretty_data {
|
||||
pager_stdin.write_all(mdbuf.as_slice()).ok()?;
|
||||
} else {
|
||||
pager_stdin.write_all(content.as_bytes()).ok()?;
|
||||
};
|
||||
|
||||
if !fmt_success {
|
||||
safe_print!("{content}");
|
||||
}
|
||||
pager.wait().ok()?;
|
||||
};
|
||||
if pager_res.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
// The pager failed. Try to print pretty output to stdout.
|
||||
if let Some((bufwtr, mdbuf)) = &pretty_data
|
||||
&& bufwtr.print(&mdbuf).is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Everything failed. Print the raw markdown text.
|
||||
safe_print!("{content}");
|
||||
}
|
||||
|
||||
fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::error::Error;
|
||||
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
@ -93,3 +95,9 @@ pub(crate) struct IceFlags {
|
|||
#[derive(Diagnostic)]
|
||||
#[diag(driver_impl_ice_exclude_cargo_defaults)]
|
||||
pub(crate) struct IceExcludeCargoDefaults;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(driver_impl_unstable_feature_usage)]
|
||||
pub(crate) struct UnstableFeatureUsage {
|
||||
pub error: Box<dyn Error>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1382,7 +1382,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
|
|||
fragment.make_foreign_items()
|
||||
}
|
||||
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||
walk_flat_map_item(visitor, self)
|
||||
walk_flat_map_foreign_item(visitor, self)
|
||||
}
|
||||
fn is_mac_call(&self) -> bool {
|
||||
matches!(self.kind, ForeignItemKind::MacCall(..))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::token::{self, Token, TokenKind};
|
||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, DiagMessage};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
|
|
@ -68,7 +68,9 @@ pub(super) fn failed_to_match_macro(
|
|||
|
||||
if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
|
||||
&& (matches!(expected_token.kind, TokenKind::Interpolated(_))
|
||||
|| matches!(token.kind, TokenKind::Interpolated(_)))
|
||||
|| matches!(token.kind, TokenKind::Interpolated(_))
|
||||
|| matches!(expected_token.kind, TokenKind::OpenDelim(Delimiter::Invisible(_)))
|
||||
|| matches!(token.kind, TokenKind::OpenDelim(Delimiter::Invisible(_))))
|
||||
{
|
||||
err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens");
|
||||
err.note("see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information");
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
|
|||
&& let mbe::TokenTree::Token(bang) = bang
|
||||
&& let TokenKind::Not = bang.kind
|
||||
&& let mbe::TokenTree::Delimited(.., del) = args
|
||||
&& del.delim != Delimiter::Invisible
|
||||
&& !del.delim.skip()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -165,11 +165,12 @@ fn parse_tree<'a>(
|
|||
// during parsing.
|
||||
let mut next = outer_trees.next();
|
||||
let mut trees: Box<dyn Iterator<Item = &tokenstream::TokenTree>>;
|
||||
if let Some(tokenstream::TokenTree::Delimited(.., Delimiter::Invisible, tts)) = next {
|
||||
trees = Box::new(tts.trees());
|
||||
next = trees.next();
|
||||
} else {
|
||||
trees = Box::new(outer_trees);
|
||||
match next {
|
||||
Some(tokenstream::TokenTree::Delimited(.., delim, tts)) if delim.skip() => {
|
||||
trees = Box::new(tts.trees());
|
||||
next = trees.next();
|
||||
}
|
||||
_ => trees = Box::new(outer_trees),
|
||||
}
|
||||
|
||||
match next {
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ impl MutVisitor for PlaceholderExpander {
|
|||
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
||||
match item.kind {
|
||||
ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
|
||||
_ => walk_flat_map_item(self, item),
|
||||
_ => walk_flat_map_foreign_item(self, item),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ impl FromInternal<token::Delimiter> for Delimiter {
|
|||
token::Delimiter::Parenthesis => Delimiter::Parenthesis,
|
||||
token::Delimiter::Brace => Delimiter::Brace,
|
||||
token::Delimiter::Bracket => Delimiter::Bracket,
|
||||
token::Delimiter::Invisible => Delimiter::None,
|
||||
token::Delimiter::Invisible(_) => Delimiter::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ impl ToInternal<token::Delimiter> for Delimiter {
|
|||
Delimiter::Parenthesis => token::Delimiter::Parenthesis,
|
||||
Delimiter::Brace => token::Delimiter::Brace,
|
||||
Delimiter::Bracket => token::Delimiter::Bracket,
|
||||
Delimiter::None => token::Delimiter::Invisible,
|
||||
Delimiter::None => token::Delimiter::Invisible(token::InvisibleOrigin::ProcMacro),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@ edition = "2021"
|
|||
# tidy-alphabetical-start
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
serde = { version = "1.0.125", features = [ "derive" ] }
|
||||
serde_json = "1.0.59"
|
||||
# tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
//! List of the unstable feature gates.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::{Symbol, sym};
|
||||
|
|
@ -651,6 +653,54 @@ declare_features! (
|
|||
// -------------------------------------------------------------------------
|
||||
);
|
||||
|
||||
impl Features {
|
||||
pub fn dump_feature_usage_metrics(
|
||||
&self,
|
||||
metrics_path: PathBuf,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
#[derive(serde::Serialize)]
|
||||
struct LibFeature {
|
||||
symbol: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct LangFeature {
|
||||
symbol: String,
|
||||
since: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct FeatureUsage {
|
||||
lib_features: Vec<LibFeature>,
|
||||
lang_features: Vec<LangFeature>,
|
||||
}
|
||||
|
||||
let metrics_file = std::fs::File::create(metrics_path)?;
|
||||
let metrics_file = std::io::BufWriter::new(metrics_file);
|
||||
|
||||
let lib_features = self
|
||||
.enabled_lib_features
|
||||
.iter()
|
||||
.map(|EnabledLibFeature { gate_name, .. }| LibFeature { symbol: gate_name.to_string() })
|
||||
.collect();
|
||||
|
||||
let lang_features = self
|
||||
.enabled_lang_features
|
||||
.iter()
|
||||
.map(|EnabledLangFeature { gate_name, stable_since, .. }| LangFeature {
|
||||
symbol: gate_name.to_string(),
|
||||
since: stable_since.map(|since| since.to_string()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let feature_usage = FeatureUsage { lib_features, lang_features };
|
||||
|
||||
serde_json::to_writer(metrics_file, &feature_usage)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Some features are not allowed to be used together at the same time, if
|
||||
/// the two are present, produce an error.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -339,6 +339,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||
|
||||
let misc_cause = ObligationCause::misc(span, def_id);
|
||||
// FIXME: We should just register the item bounds here, rather than equating.
|
||||
// FIXME(const_trait_impl): When we do that, please make sure to also register
|
||||
// the `~const` bounds.
|
||||
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
|
||||
Ok(()) => {}
|
||||
Err(ty_err) => {
|
||||
|
|
|
|||
|
|
@ -2083,7 +2083,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
||||
if tcx.is_conditionally_const(impl_ty_def_id) {
|
||||
obligations.extend(
|
||||
tcx.implied_const_bounds(trait_ty.def_id)
|
||||
tcx.explicit_implied_const_bounds(trait_ty.def_id)
|
||||
.iter_instantiated_copied(tcx, rebased_args)
|
||||
.map(|(c, span)| {
|
||||
traits::Obligation::new(
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
predicates_of::explicit_supertraits_containing_assoc_item,
|
||||
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
||||
const_conditions: predicates_of::const_conditions,
|
||||
implied_const_bounds: predicates_of::implied_const_bounds,
|
||||
explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
|
||||
type_param_predicates: predicates_of::type_param_predicates,
|
||||
trait_def,
|
||||
adt_def,
|
||||
|
|
@ -340,6 +340,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||
self.tcx.ensure().explicit_item_super_predicates(def_id);
|
||||
self.tcx.ensure().item_bounds(def_id);
|
||||
self.tcx.ensure().item_super_predicates(def_id);
|
||||
if self.tcx.is_conditionally_const(def_id) {
|
||||
self.tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||
self.tcx.ensure().const_conditions(def_id);
|
||||
}
|
||||
intravisit::walk_opaque_ty(self, opaque);
|
||||
}
|
||||
|
||||
|
|
@ -682,6 +686,10 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
tcx.ensure().generics_of(item.owner_id);
|
||||
tcx.ensure().type_of(item.owner_id);
|
||||
tcx.ensure().predicates_of(item.owner_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||
tcx.ensure().const_conditions(def_id);
|
||||
}
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(..) => {
|
||||
tcx.ensure().codegen_fn_attrs(item.owner_id);
|
||||
|
|
|
|||
|
|
@ -959,6 +959,12 @@ pub(super) fn const_conditions<'tcx>(
|
|||
hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
|
||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||
},
|
||||
Node::OpaqueTy(opaque) => match opaque.origin {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent),
|
||||
hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
// N.B. Tuple ctors are unconditionally constant.
|
||||
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
|
||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||
|
|
@ -1018,7 +1024,7 @@ pub(super) fn const_conditions<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn implied_const_bounds<'tcx>(
|
||||
pub(super) fn explicit_implied_const_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||
|
|
@ -1034,10 +1040,11 @@ pub(super) fn implied_const_bounds<'tcx>(
|
|||
PredicateFilter::SelfConstIfConst,
|
||||
)
|
||||
}
|
||||
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
|
||||
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
|
||||
| Node::OpaqueTy(_) => {
|
||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
|
||||
}
|
||||
_ => bug!("implied_const_bounds called on wrong item: {def_id:?}"),
|
||||
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
|
||||
};
|
||||
|
||||
bounds.map_bound(|bounds| {
|
||||
|
|
|
|||
|
|
@ -1106,7 +1106,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.collect::<String>()
|
||||
),
|
||||
[(only, _)] => only.to_string(),
|
||||
[] => "this type".to_string(),
|
||||
[] => bug!("expected one segment to deny"),
|
||||
};
|
||||
|
||||
let arg_spans: Vec<Span> = segments
|
||||
|
|
@ -1136,7 +1136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
"s",
|
||||
),
|
||||
[only] => (only.to_string(), ""),
|
||||
[] => unreachable!("expected at least one generic to prohibit"),
|
||||
[] => bug!("expected at least one generic to prohibit"),
|
||||
};
|
||||
let last_span = *arg_spans.last().unwrap();
|
||||
let span: MultiSpan = arg_spans.into();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use rustc_span::symbol::{Ident, kw, sym};
|
|||
use rustc_span::{
|
||||
DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span, Symbol, edit_distance,
|
||||
};
|
||||
use rustc_trait_selection::error_reporting::traits::DefIdOrName;
|
||||
use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedNote;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
|
|
@ -45,50 +46,6 @@ use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
|
|||
use crate::{Expectation, FnCtxt};
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||
let tcx = self.tcx;
|
||||
match ty.kind() {
|
||||
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
|
||||
// so we look for these beforehand.
|
||||
// FIXME(async_closures): These don't impl `FnOnce` by default.
|
||||
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(..) => true,
|
||||
// If it's not a simple function, look for things which implement `FnOnce`.
|
||||
_ => {
|
||||
let Some(fn_once) = tcx.lang_items().fn_once_trait() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
// This conditional prevents us from asking to call errors and unresolved types.
|
||||
// It might seem that we can use `predicate_must_hold_modulo_regions`,
|
||||
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
|
||||
// type resolution always gives a "maybe" here.
|
||||
if self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
|
||||
info!("check deref {:?} error", ty);
|
||||
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
|
||||
info!("check deref {:?} impl FnOnce", ty);
|
||||
self.probe(|_| {
|
||||
let trait_ref =
|
||||
ty::TraitRef::new(tcx, fn_once, [ty, self.next_ty_var(span)]);
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
let obligation = Obligation::misc(
|
||||
tcx,
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref,
|
||||
);
|
||||
self.predicate_may_hold(&obligation)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||
self.autoderef(span, ty)
|
||||
.silence_errors()
|
||||
|
|
@ -2367,12 +2324,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let is_accessible = field.vis.is_accessible_from(scope, tcx);
|
||||
|
||||
if is_accessible {
|
||||
if self.is_fn_ty(field_ty, span) {
|
||||
if let Some((what, _, _)) = self.extract_callable_info(field_ty) {
|
||||
let what = match what {
|
||||
DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id),
|
||||
DefIdOrName::Name(what) => what,
|
||||
};
|
||||
let expr_span = expr.span.to(item_name.span);
|
||||
err.multipart_suggestion(
|
||||
format!(
|
||||
"to call the function stored in `{item_name}`, \
|
||||
surround the field access with parentheses",
|
||||
"to call the {what} stored in `{item_name}`, \
|
||||
surround the field access with parentheses",
|
||||
),
|
||||
vec![
|
||||
(expr_span.shrink_to_lo(), '('.to_string()),
|
||||
|
|
|
|||
|
|
@ -574,9 +574,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// unexpected region errors.
|
||||
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
|
||||
|
||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
||||
let replace_opaques_in = |clause: ty::Clause<'tcx>, goals: &mut Vec<_>| {
|
||||
clause.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
// We can't normalize associated types from `rustc_infer`,
|
||||
|
|
@ -612,11 +611,31 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
},
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = replace_opaques_in(predicate, goals);
|
||||
|
||||
// Require that the predicate holds for the concrete type.
|
||||
debug!(?predicate);
|
||||
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||
}
|
||||
|
||||
// If this opaque is being defined and it's conditionally const,
|
||||
if self.tcx.is_conditionally_const(def_id) {
|
||||
let item_bounds = tcx.explicit_implied_const_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = replace_opaques_in(
|
||||
predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe),
|
||||
goals,
|
||||
);
|
||||
|
||||
// Require that the predicate holds for the concrete type.
|
||||
debug!(?predicate);
|
||||
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,15 +230,16 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
|||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
|
||||
self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt {
|
||||
ast_visit::AssocCtxt::Trait => {
|
||||
lint_callback!(cx, check_trait_item, item);
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
}
|
||||
ast_visit::AssocCtxt::Impl => {
|
||||
lint_callback!(cx, check_impl_item, item);
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
self.with_lint_attrs(item.id, &item.attrs, |cx| {
|
||||
match ctxt {
|
||||
ast_visit::AssocCtxt::Trait => {
|
||||
lint_callback!(cx, check_trait_item, item);
|
||||
}
|
||||
ast_visit::AssocCtxt::Impl => {
|
||||
lint_callback!(cx, check_impl_item, item);
|
||||
}
|
||||
}
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
bitflags = "2.4.1"
|
||||
libc = "0.2"
|
||||
libloading = "0.8.0"
|
||||
odht = { version = "0.3.1", features = ["nightly"] }
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
|
|
|
|||
|
|
@ -540,6 +540,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
Some(cnum)
|
||||
}
|
||||
Err(err) => {
|
||||
debug!("failed to resolve crate {} {:?}", name, dep_kind);
|
||||
let missing_core =
|
||||
self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
|
||||
err.report(self.sess, span, missing_core);
|
||||
|
|
@ -588,6 +589,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
match self.load(&mut locator)? {
|
||||
Some(res) => (res, None),
|
||||
None => {
|
||||
info!("falling back to loading proc_macro");
|
||||
dep_kind = CrateDepKind::MacrosOnly;
|
||||
match self.load_proc_macro(&mut locator, path_kind, host_hash)? {
|
||||
Some(res) => res,
|
||||
|
|
@ -599,6 +601,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
|
||||
match result {
|
||||
(LoadResult::Previous(cnum), None) => {
|
||||
info!("library for `{}` was loaded previously", name);
|
||||
// When `private_dep` is none, it indicates the directly dependent crate. If it is
|
||||
// not specified by `--extern` on command line parameters, it may be
|
||||
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
|
||||
|
|
@ -613,6 +616,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
Ok(cnum)
|
||||
}
|
||||
(LoadResult::Loaded(library), host_library) => {
|
||||
info!("register newly loaded library for `{}`", name);
|
||||
self.register_crate(host_library, root, library, dep_kind, name, private_dep)
|
||||
}
|
||||
_ => panic!(),
|
||||
|
|
@ -696,7 +700,25 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
|||
stable_crate_id: StableCrateId,
|
||||
) -> Result<&'static [ProcMacro], CrateError> {
|
||||
let sym_name = self.sess.generate_proc_macro_decls_symbol(stable_crate_id);
|
||||
Ok(unsafe { *load_symbol_from_dylib::<*const &[ProcMacro]>(path, &sym_name)? })
|
||||
debug!("trying to dlsym proc_macros {} for symbol `{}`", path.display(), sym_name);
|
||||
|
||||
unsafe {
|
||||
let result = load_symbol_from_dylib::<*const &[ProcMacro]>(path, &sym_name);
|
||||
match result {
|
||||
Ok(result) => {
|
||||
debug!("loaded dlsym proc_macros {} for symbol `{}`", path.display(), sym_name);
|
||||
Ok(*result)
|
||||
}
|
||||
Err(err) => {
|
||||
debug!(
|
||||
"failed to dlsym proc_macros {} for symbol `{}`",
|
||||
path.display(),
|
||||
sym_name
|
||||
);
|
||||
Err(err.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
|
||||
|
|
@ -1141,6 +1163,29 @@ fn format_dlopen_err(e: &(dyn std::error::Error + 'static)) -> String {
|
|||
e.sources().map(|e| format!(": {e}")).collect()
|
||||
}
|
||||
|
||||
fn attempt_load_dylib(path: &Path) -> Result<libloading::Library, libloading::Error> {
|
||||
#[cfg(target_os = "aix")]
|
||||
if let Some(ext) = path.extension()
|
||||
&& ext.eq("a")
|
||||
{
|
||||
// On AIX, we ship all libraries as .a big_af archive
|
||||
// the expected format is lib<name>.a(libname.so) for the actual
|
||||
// dynamic library
|
||||
let library_name = path.file_stem().expect("expect a library name");
|
||||
let mut archive_member = OsString::from("a(");
|
||||
archive_member.push(library_name);
|
||||
archive_member.push(".so)");
|
||||
let new_path = path.with_extension(archive_member);
|
||||
|
||||
// On AIX, we need RTLD_MEMBER to dlopen an archived shared
|
||||
let flags = libc::RTLD_LAZY | libc::RTLD_LOCAL | libc::RTLD_MEMBER;
|
||||
return unsafe { libloading::os::unix::Library::open(Some(&new_path), flags) }
|
||||
.map(|lib| lib.into());
|
||||
}
|
||||
|
||||
unsafe { libloading::Library::new(&path) }
|
||||
}
|
||||
|
||||
// On Windows the compiler would sometimes intermittently fail to open the
|
||||
// proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the
|
||||
// system still holds a lock on the file, so we retry a few times before calling it
|
||||
|
|
@ -1151,7 +1196,8 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
|
|||
let mut last_error = None;
|
||||
|
||||
for attempt in 0..max_attempts {
|
||||
match unsafe { libloading::Library::new(&path) } {
|
||||
debug!("Attempt to load proc-macro `{}`.", path.display());
|
||||
match attempt_load_dylib(path) {
|
||||
Ok(lib) => {
|
||||
if attempt > 0 {
|
||||
debug!(
|
||||
|
|
@ -1165,6 +1211,7 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
|
|||
Err(err) => {
|
||||
// Only try to recover from this specific error.
|
||||
if !matches!(err, libloading::Error::LoadLibraryExW { .. }) {
|
||||
debug!("Failed to load proc-macro `{}`. Not retrying", path.display());
|
||||
let err = format_dlopen_err(&err);
|
||||
// We include the path of the dylib in the error ourselves, so
|
||||
// if it's in the error, we strip it.
|
||||
|
|
|
|||
|
|
@ -847,7 +847,10 @@ fn get_metadata_section<'p>(
|
|||
)));
|
||||
};
|
||||
match blob.check_compatibility(cfg_version) {
|
||||
Ok(()) => Ok(blob),
|
||||
Ok(()) => {
|
||||
debug!("metadata blob read okay");
|
||||
Ok(blob)
|
||||
}
|
||||
Err(None) => Err(MetadataError::LoadFailure(format!(
|
||||
"invalid metadata version found: {}",
|
||||
filename.display()
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ provide! { tcx, def_id, other, cdata,
|
|||
defaultness => { table_direct }
|
||||
constness => { table_direct }
|
||||
const_conditions => { table }
|
||||
implied_const_bounds => { table_defaulted_array }
|
||||
explicit_implied_const_bounds => { table_defaulted_array }
|
||||
coerce_unsized_info => {
|
||||
Ok(cdata
|
||||
.root
|
||||
|
|
|
|||
|
|
@ -1463,8 +1463,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||
module_children.iter().map(|child| child.res.def_id().index));
|
||||
if self.tcx.is_const_trait(def_id) {
|
||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
if let DefKind::TraitAlias = def_kind {
|
||||
|
|
@ -1532,6 +1532,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
self.encode_explicit_item_super_predicates(def_id);
|
||||
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
|
||||
self.encode_precise_capturing_args(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
|
|
@ -1654,8 +1658,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
self.encode_explicit_item_bounds(def_id);
|
||||
self.encode_explicit_item_super_predicates(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ define_tables! {
|
|||
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
||||
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
||||
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
||||
|
|
|
|||
|
|
@ -697,7 +697,7 @@ rustc_queries! {
|
|||
separate_provide_extern
|
||||
}
|
||||
|
||||
query implied_const_bounds(
|
||||
query explicit_implied_const_bounds(
|
||||
key: DefId
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
||||
|
|
|
|||
|
|
@ -393,12 +393,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
fn implied_const_bounds(
|
||||
fn explicit_implied_const_bounds(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||
self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2110,7 +2110,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
||||
}
|
||||
}
|
||||
DefKind::Closure | DefKind::OpaqueTy => {
|
||||
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
|
||||
hir::OpaqueTyOrigin::AsyncFn { .. } => false,
|
||||
// FIXME(const_trait_impl): ATPITs could be conditionally const?
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => false,
|
||||
},
|
||||
DefKind::Closure => {
|
||||
// Closures and RPITs will eventually have const conditions
|
||||
// for `~const` bounds.
|
||||
false
|
||||
|
|
|
|||
|
|
@ -537,8 +537,45 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
self.requires_unsafe(expr.span, DerefOfRawPointer);
|
||||
}
|
||||
}
|
||||
ExprKind::InlineAsm { .. } => {
|
||||
ExprKind::InlineAsm(box InlineAsmExpr {
|
||||
asm_macro: _,
|
||||
ref operands,
|
||||
template: _,
|
||||
options: _,
|
||||
line_spans: _,
|
||||
}) => {
|
||||
self.requires_unsafe(expr.span, UseOfInlineAssembly);
|
||||
|
||||
// For inline asm, do not use `walk_expr`, since we want to handle the label block
|
||||
// specially.
|
||||
for op in &**operands {
|
||||
use rustc_middle::thir::InlineAsmOperand::*;
|
||||
match op {
|
||||
In { expr, reg: _ }
|
||||
| Out { expr: Some(expr), reg: _, late: _ }
|
||||
| InOut { expr, reg: _, late: _ } => self.visit_expr(&self.thir()[*expr]),
|
||||
SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
|
||||
self.visit_expr(&self.thir()[*in_expr]);
|
||||
if let Some(out_expr) = out_expr {
|
||||
self.visit_expr(&self.thir()[*out_expr]);
|
||||
}
|
||||
}
|
||||
Out { expr: None, reg: _, late: _ }
|
||||
| Const { value: _, span: _ }
|
||||
| SymFn { value: _, span: _ }
|
||||
| SymStatic { def_id: _ } => {}
|
||||
Label { block } => {
|
||||
// Label blocks are safe context.
|
||||
// `asm!()` is forced to be wrapped inside unsafe. If there's no special
|
||||
// treatment, the label blocks would also always be unsafe with no way
|
||||
// of opting out.
|
||||
self.in_safety_context(SafetyContext::Safe, |this| {
|
||||
visit::walk_block(this, &this.thir()[*block])
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
ExprKind::Adt(box AdtExpr {
|
||||
adt_def,
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ where
|
|||
|
||||
/// Assemble additional assumptions for an alias that are not included
|
||||
/// in the item bounds of the alias. For now, this is limited to the
|
||||
/// `implied_const_bounds` for an associated type.
|
||||
/// `explicit_implied_const_bounds` for an associated type.
|
||||
fn consider_additional_alias_assumptions(
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
|
|
|
|||
|
|
@ -84,12 +84,9 @@ where
|
|||
let cx = ecx.cx();
|
||||
let mut candidates = vec![];
|
||||
|
||||
// FIXME(const_trait_impl): We elaborate here because the implied const bounds
|
||||
// aren't necessarily elaborated. We probably should prefix this query
|
||||
// with `explicit_`...
|
||||
for clause in elaborate::elaborate(
|
||||
cx,
|
||||
cx.implied_const_bounds(alias_ty.def_id)
|
||||
cx.explicit_implied_const_bounds(alias_ty.def_id)
|
||||
.iter_instantiated(cx, alias_ty.args)
|
||||
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -216,6 +216,9 @@ parse_expected_identifier_found_doc_comment = expected identifier, found doc com
|
|||
parse_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token}`
|
||||
parse_expected_identifier_found_keyword = expected identifier, found keyword
|
||||
parse_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token}`
|
||||
parse_expected_identifier_found_metavar = expected identifier, found metavariable
|
||||
# This one deliberately doesn't print a token.
|
||||
parse_expected_identifier_found_metavar_str = expected identifier, found metavariable
|
||||
parse_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier
|
||||
parse_expected_identifier_found_reserved_identifier_str = expected identifier, found reserved identifier `{$token}`
|
||||
parse_expected_identifier_found_reserved_keyword = expected identifier, found reserved keyword
|
||||
|
|
@ -227,6 +230,8 @@ parse_expected_mut_or_const_in_raw_pointer_type = expected `mut` or `const` keyw
|
|||
|
||||
parse_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token}`
|
||||
parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}`
|
||||
# This one deliberately doesn't print a token.
|
||||
parse_expected_semi_found_metavar_str = expected `;`, found metavariable
|
||||
parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}`
|
||||
parse_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token}`
|
||||
parse_expected_semi_found_str = expected `;`, found `{$token}`
|
||||
|
|
@ -864,6 +869,8 @@ parse_unexpected_token_after_not_logical = use `!` to perform logical negation
|
|||
parse_unexpected_token_after_struct_name = expected `where`, `{"{"}`, `(`, or `;` after struct name
|
||||
parse_unexpected_token_after_struct_name_found_doc_comment = expected `where`, `{"{"}`, `(`, or `;` after struct name, found doc comment `{$token}`
|
||||
parse_unexpected_token_after_struct_name_found_keyword = expected `where`, `{"{"}`, `(`, or `;` after struct name, found keyword `{$token}`
|
||||
# This one deliberately doesn't print a token.
|
||||
parse_unexpected_token_after_struct_name_found_metavar = expected `where`, `{"{"}`, `(`, or `;` after struct name, found metavar
|
||||
parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}`, `(`, or `;` after struct name, found `{$token}`
|
||||
|
||||
parse_unexpected_token_after_struct_name_found_reserved_identifier = expected `where`, `{"{"}`, `(`, or `;` after struct name, found reserved identifier `{$token}`
|
||||
|
|
|
|||
|
|
@ -1086,6 +1086,8 @@ pub(crate) enum ExpectedIdentifierFound {
|
|||
ReservedKeyword(#[primary_span] Span),
|
||||
#[label(parse_expected_identifier_found_doc_comment)]
|
||||
DocComment(#[primary_span] Span),
|
||||
#[label(parse_expected_identifier_found_metavar)]
|
||||
MetaVar(#[primary_span] Span),
|
||||
#[label(parse_expected_identifier)]
|
||||
Other(#[primary_span] Span),
|
||||
}
|
||||
|
|
@ -1099,6 +1101,7 @@ impl ExpectedIdentifierFound {
|
|||
Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
|
||||
Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
|
||||
Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
|
||||
Some(TokenDescription::MetaVar(_)) => ExpectedIdentifierFound::MetaVar,
|
||||
None => ExpectedIdentifierFound::Other,
|
||||
})(span)
|
||||
}
|
||||
|
|
@ -1117,6 +1120,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
|
|||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
let token_descr = TokenDescription::from_token(&self.token);
|
||||
|
||||
let mut add_token = true;
|
||||
let mut diag = Diag::new(dcx, level, match token_descr {
|
||||
Some(TokenDescription::ReservedIdentifier) => {
|
||||
fluent::parse_expected_identifier_found_reserved_identifier_str
|
||||
|
|
@ -1128,10 +1132,16 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
|
|||
Some(TokenDescription::DocComment) => {
|
||||
fluent::parse_expected_identifier_found_doc_comment_str
|
||||
}
|
||||
Some(TokenDescription::MetaVar(_)) => {
|
||||
add_token = false;
|
||||
fluent::parse_expected_identifier_found_metavar_str
|
||||
}
|
||||
None => fluent::parse_expected_identifier_found_str,
|
||||
});
|
||||
diag.span(self.span);
|
||||
diag.arg("token", self.token);
|
||||
if add_token {
|
||||
diag.arg("token", self.token);
|
||||
}
|
||||
|
||||
if let Some(sugg) = self.suggest_raw {
|
||||
sugg.add_to_diag(&mut diag);
|
||||
|
|
@ -1171,6 +1181,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
|
|||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
let token_descr = TokenDescription::from_token(&self.token);
|
||||
|
||||
let mut add_token = true;
|
||||
let mut diag = Diag::new(dcx, level, match token_descr {
|
||||
Some(TokenDescription::ReservedIdentifier) => {
|
||||
fluent::parse_expected_semi_found_reserved_identifier_str
|
||||
|
|
@ -1180,10 +1191,16 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
|
|||
fluent::parse_expected_semi_found_reserved_keyword_str
|
||||
}
|
||||
Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
|
||||
Some(TokenDescription::MetaVar(_)) => {
|
||||
add_token = false;
|
||||
fluent::parse_expected_semi_found_metavar_str
|
||||
}
|
||||
None => fluent::parse_expected_semi_found_str,
|
||||
});
|
||||
diag.span(self.span);
|
||||
diag.arg("token", self.token);
|
||||
if add_token {
|
||||
diag.arg("token", self.token);
|
||||
}
|
||||
|
||||
if let Some(unexpected_token_label) = self.unexpected_token_label {
|
||||
diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
|
||||
|
|
@ -1925,6 +1942,12 @@ pub(crate) enum UnexpectedTokenAfterStructName {
|
|||
span: Span,
|
||||
token: Token,
|
||||
},
|
||||
#[diag(parse_unexpected_token_after_struct_name_found_metavar)]
|
||||
MetaVar {
|
||||
#[primary_span]
|
||||
#[label(parse_unexpected_token_after_struct_name)]
|
||||
span: Span,
|
||||
},
|
||||
#[diag(parse_unexpected_token_after_struct_name_found_other)]
|
||||
Other {
|
||||
#[primary_span]
|
||||
|
|
@ -1941,6 +1964,7 @@ impl UnexpectedTokenAfterStructName {
|
|||
Some(TokenDescription::Keyword) => Self::Keyword { span, token },
|
||||
Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
|
||||
Some(TokenDescription::DocComment) => Self::DocComment { span, token },
|
||||
Some(TokenDescription::MetaVar(_)) => Self::MetaVar { span },
|
||||
None => Self::Other { span, token },
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,11 +43,19 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> {
|
|||
let mut buf = Vec::new();
|
||||
loop {
|
||||
match self.token.kind {
|
||||
token::OpenDelim(delim) => buf.push(match self.lex_token_tree_open_delim(delim) {
|
||||
Ok(val) => val,
|
||||
Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
|
||||
}),
|
||||
token::OpenDelim(delim) => {
|
||||
// Invisible delimiters cannot occur here because `TokenTreesReader` parses
|
||||
// code directly from strings, with no macro expansion involved.
|
||||
debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
|
||||
buf.push(match self.lex_token_tree_open_delim(delim) {
|
||||
Ok(val) => val,
|
||||
Err(errs) => return (open_spacing, TokenStream::new(buf), Err(errs)),
|
||||
})
|
||||
}
|
||||
token::CloseDelim(delim) => {
|
||||
// Invisible delimiters cannot occur here because `TokenTreesReader` parses
|
||||
// code directly from strings, with no macro expansion involved.
|
||||
debug_assert!(!matches!(delim, Delimiter::Invisible(_)));
|
||||
return (
|
||||
open_spacing,
|
||||
TokenStream::new(buf),
|
||||
|
|
|
|||
|
|
@ -510,8 +510,8 @@ fn make_attr_token_stream(
|
|||
FlatToken::Token((Token { kind: TokenKind::CloseDelim(delim), span }, spacing)) => {
|
||||
let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
|
||||
let (open_delim, open_sp, open_spacing) = frame_data.open_delim_sp.unwrap();
|
||||
assert_eq!(
|
||||
open_delim, delim,
|
||||
assert!(
|
||||
open_delim.eq_ignoring_invisible_origin(&delim),
|
||||
"Mismatched open/close delims: open={open_delim:?} close={span:?}"
|
||||
);
|
||||
let dspan = DelimSpan::from_pair(open_sp, span);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ pub(super) enum DestructuredFloat {
|
|||
/// 1.2 | 1.2e3
|
||||
MiddleDot(Symbol, Span, Span, Symbol, Span),
|
||||
/// Invalid
|
||||
Error(ErrorGuaranteed),
|
||||
Error,
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
|
|
@ -1005,7 +1005,7 @@ impl<'a> Parser<'a> {
|
|||
self.mk_expr_tuple_field_access(lo, ident1_span, base, sym1, None);
|
||||
self.mk_expr_tuple_field_access(lo, ident2_span, base1, sym2, suffix)
|
||||
}
|
||||
DestructuredFloat::Error(_) => base,
|
||||
DestructuredFloat::Error => base,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -1015,7 +1015,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn error_unexpected_after_dot(&self) -> ErrorGuaranteed {
|
||||
fn error_unexpected_after_dot(&self) {
|
||||
let actual = pprust::token_to_string(&self.token);
|
||||
let span = self.token.span;
|
||||
let sm = self.psess.source_map();
|
||||
|
|
@ -1025,7 +1025,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
_ => (span, actual),
|
||||
};
|
||||
self.dcx().emit_err(errors::UnexpectedTokenAfterDot { span, actual })
|
||||
self.dcx().emit_err(errors::UnexpectedTokenAfterDot { span, actual });
|
||||
}
|
||||
|
||||
/// We need an identifier or integer, but the next token is a float.
|
||||
|
|
@ -1111,8 +1111,8 @@ impl<'a> Parser<'a> {
|
|||
// 1.2e+3 | 1.2e-3
|
||||
[IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => {
|
||||
// See the FIXME about `TokenCursor` above.
|
||||
let guar = self.error_unexpected_after_dot();
|
||||
DestructuredFloat::Error(guar)
|
||||
self.error_unexpected_after_dot();
|
||||
DestructuredFloat::Error
|
||||
}
|
||||
_ => panic!("unexpected components in a float token: {components:?}"),
|
||||
}
|
||||
|
|
@ -1178,7 +1178,7 @@ impl<'a> Parser<'a> {
|
|||
fields.insert(start_idx, Ident::new(symbol2, span2));
|
||||
fields.insert(start_idx, Ident::new(symbol1, span1));
|
||||
}
|
||||
DestructuredFloat::Error(_) => {
|
||||
DestructuredFloat::Error => {
|
||||
trailing_dot = None;
|
||||
fields.insert(start_idx, Ident::new(symbol, self.prev_token.span));
|
||||
}
|
||||
|
|
@ -3591,11 +3591,19 @@ impl<'a> Parser<'a> {
|
|||
&& !self.token.is_reserved_ident()
|
||||
&& self.look_ahead(1, |t| {
|
||||
AssocOp::from_token(t).is_some()
|
||||
|| matches!(t.kind, token::OpenDelim(_))
|
||||
|| matches!(
|
||||
t.kind,
|
||||
token::OpenDelim(
|
||||
Delimiter::Parenthesis
|
||||
| Delimiter::Bracket
|
||||
| Delimiter::Brace
|
||||
)
|
||||
)
|
||||
|| *t == token::Dot
|
||||
})
|
||||
{
|
||||
// Looks like they tried to write a shorthand, complex expression.
|
||||
// Looks like they tried to write a shorthand, complex expression,
|
||||
// E.g.: `n + m`, `f(a)`, `a[i]`, `S { x: 3 }`, or `x.y`.
|
||||
e.span_suggestion_verbose(
|
||||
self.token.span.shrink_to_lo(),
|
||||
"try naming a field",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ pub(crate) use item::FnParseMode;
|
|||
pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
|
||||
use path::PathStyle;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, Token, TokenKind,
|
||||
};
|
||||
use rustc_ast::tokenstream::{
|
||||
AttrsTarget, DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree, TokenTreeCursor,
|
||||
};
|
||||
|
|
@ -317,7 +319,7 @@ impl TokenCursor {
|
|||
spacing,
|
||||
delim,
|
||||
));
|
||||
if delim != Delimiter::Invisible {
|
||||
if !delim.skip() {
|
||||
return (Token::new(token::OpenDelim(delim), sp.open), spacing.open);
|
||||
}
|
||||
// No open delimiter to return; continue on to the next iteration.
|
||||
|
|
@ -326,7 +328,7 @@ impl TokenCursor {
|
|||
} else if let Some((tree_cursor, span, spacing, delim)) = self.stack.pop() {
|
||||
// We have exhausted this token stream. Move back to its parent token stream.
|
||||
self.tree_cursor = tree_cursor;
|
||||
if delim != Delimiter::Invisible {
|
||||
if !delim.skip() {
|
||||
return (Token::new(token::CloseDelim(delim), span.close), spacing.close);
|
||||
}
|
||||
// No close delimiter to return; continue on to the next iteration.
|
||||
|
|
@ -410,6 +412,12 @@ pub(super) enum TokenDescription {
|
|||
Keyword,
|
||||
ReservedKeyword,
|
||||
DocComment,
|
||||
|
||||
// Expanded metavariables are wrapped in invisible delimiters which aren't
|
||||
// pretty-printed. In error messages we must handle these specially
|
||||
// otherwise we get confusing things in messages like "expected `(`, found
|
||||
// ``". It's better to say e.g. "expected `(`, found type metavariable".
|
||||
MetaVar(MetaVarKind),
|
||||
}
|
||||
|
||||
impl TokenDescription {
|
||||
|
|
@ -419,26 +427,29 @@ impl TokenDescription {
|
|||
_ if token.is_used_keyword() => Some(TokenDescription::Keyword),
|
||||
_ if token.is_unused_keyword() => Some(TokenDescription::ReservedKeyword),
|
||||
token::DocComment(..) => Some(TokenDescription::DocComment),
|
||||
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(kind))) => {
|
||||
Some(TokenDescription::MetaVar(kind))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn token_descr(token: &Token) -> String {
|
||||
let name = pprust::token_to_string(token).to_string();
|
||||
let s = pprust::token_to_string(token).to_string();
|
||||
|
||||
let kind = match (TokenDescription::from_token(token), &token.kind) {
|
||||
(Some(TokenDescription::ReservedIdentifier), _) => Some("reserved identifier"),
|
||||
(Some(TokenDescription::Keyword), _) => Some("keyword"),
|
||||
(Some(TokenDescription::ReservedKeyword), _) => Some("reserved keyword"),
|
||||
(Some(TokenDescription::DocComment), _) => Some("doc comment"),
|
||||
(None, TokenKind::NtIdent(..)) => Some("identifier"),
|
||||
(None, TokenKind::NtLifetime(..)) => Some("lifetime"),
|
||||
(None, TokenKind::Interpolated(node)) => Some(node.descr()),
|
||||
(None, _) => None,
|
||||
};
|
||||
|
||||
if let Some(kind) = kind { format!("{kind} `{name}`") } else { format!("`{name}`") }
|
||||
match (TokenDescription::from_token(token), &token.kind) {
|
||||
(Some(TokenDescription::ReservedIdentifier), _) => format!("reserved identifier `{s}`"),
|
||||
(Some(TokenDescription::Keyword), _) => format!("keyword `{s}`"),
|
||||
(Some(TokenDescription::ReservedKeyword), _) => format!("reserved keyword `{s}`"),
|
||||
(Some(TokenDescription::DocComment), _) => format!("doc comment `{s}`"),
|
||||
// Deliberately doesn't print `s`, which is empty.
|
||||
(Some(TokenDescription::MetaVar(kind)), _) => format!("`{kind}` metavariable"),
|
||||
(None, TokenKind::NtIdent(..)) => format!("identifier `{s}`"),
|
||||
(None, TokenKind::NtLifetime(..)) => format!("lifetime `{s}`"),
|
||||
(None, TokenKind::Interpolated(node)) => format!("{} `{s}`", node.descr()),
|
||||
(None, _) => format!("`{s}`"),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
|
|
@ -1163,7 +1174,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
debug_assert!(!matches!(
|
||||
next.0.kind,
|
||||
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible)
|
||||
token::OpenDelim(delim) | token::CloseDelim(delim) if delim.skip()
|
||||
));
|
||||
self.inlined_bump_with(next)
|
||||
}
|
||||
|
|
@ -1187,7 +1198,7 @@ impl<'a> Parser<'a> {
|
|||
match tree {
|
||||
TokenTree::Token(token, _) => return looker(token),
|
||||
&TokenTree::Delimited(dspan, _, delim, _) => {
|
||||
if delim != Delimiter::Invisible {
|
||||
if !delim.skip() {
|
||||
return looker(&Token::new(token::OpenDelim(delim), dspan.open));
|
||||
}
|
||||
}
|
||||
|
|
@ -1197,7 +1208,7 @@ impl<'a> Parser<'a> {
|
|||
// The tree cursor lookahead went (one) past the end of the
|
||||
// current token tree. Try to return a close delimiter.
|
||||
if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last()
|
||||
&& delim != Delimiter::Invisible
|
||||
&& !delim.skip()
|
||||
{
|
||||
// We are not in the outermost token stream, so we have
|
||||
// delimiters. Also, those delimiters are not skipped.
|
||||
|
|
@ -1216,7 +1227,7 @@ impl<'a> Parser<'a> {
|
|||
token = cursor.next().0;
|
||||
if matches!(
|
||||
token.kind,
|
||||
token::OpenDelim(Delimiter::Invisible) | token::CloseDelim(Delimiter::Invisible)
|
||||
token::OpenDelim(delim) | token::CloseDelim(delim) if delim.skip()
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::token::Nonterminal::*;
|
||||
use rustc_ast::token::NtExprKind::*;
|
||||
use rustc_ast::token::NtPatKind::*;
|
||||
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token};
|
||||
use rustc_ast::token::{
|
||||
self, Delimiter, InvisibleOrigin, MetaVarKind, Nonterminal, NonterminalKind, Token,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::PResult;
|
||||
|
|
@ -22,7 +24,28 @@ impl<'a> Parser<'a> {
|
|||
#[inline]
|
||||
pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool {
|
||||
/// Checks whether the non-terminal may contain a single (non-keyword) identifier.
|
||||
fn may_be_ident(nt: &token::Nonterminal) -> bool {
|
||||
fn may_be_ident(kind: MetaVarKind) -> bool {
|
||||
match kind {
|
||||
MetaVarKind::Stmt
|
||||
| MetaVarKind::Pat(_)
|
||||
| MetaVarKind::Expr { .. }
|
||||
| MetaVarKind::Ty
|
||||
| MetaVarKind::Literal // `true`, `false`
|
||||
| MetaVarKind::Meta
|
||||
| MetaVarKind::Path => true,
|
||||
|
||||
MetaVarKind::Item
|
||||
| MetaVarKind::Block
|
||||
| MetaVarKind::Vis => false,
|
||||
|
||||
MetaVarKind::Ident
|
||||
| MetaVarKind::Lifetime
|
||||
| MetaVarKind::TT => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Old variant of `may_be_ident`. Being phased out.
|
||||
fn nt_may_be_ident(nt: &Nonterminal) -> bool {
|
||||
match nt {
|
||||
NtStmt(_)
|
||||
| NtPat(_)
|
||||
|
|
@ -69,7 +92,8 @@ impl<'a> Parser<'a> {
|
|||
| token::Ident(..)
|
||||
| token::NtIdent(..)
|
||||
| token::NtLifetime(..)
|
||||
| token::Interpolated(_) => true,
|
||||
| token::Interpolated(_)
|
||||
| token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(_))) => true,
|
||||
_ => token.can_begin_type(),
|
||||
},
|
||||
NonterminalKind::Block => match &token.kind {
|
||||
|
|
@ -79,11 +103,29 @@ impl<'a> Parser<'a> {
|
|||
NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true,
|
||||
NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) | NtVis(_) => false,
|
||||
},
|
||||
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k {
|
||||
MetaVarKind::Block
|
||||
| MetaVarKind::Stmt
|
||||
| MetaVarKind::Expr { .. }
|
||||
| MetaVarKind::Literal => true,
|
||||
MetaVarKind::Item
|
||||
| MetaVarKind::Pat(_)
|
||||
| MetaVarKind::Ty
|
||||
| MetaVarKind::Meta
|
||||
| MetaVarKind::Path
|
||||
| MetaVarKind::Vis => false,
|
||||
MetaVarKind::Lifetime | MetaVarKind::Ident | MetaVarKind::TT => {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::Path | NonterminalKind::Meta => match &token.kind {
|
||||
token::PathSep | token::Ident(..) | token::NtIdent(..) => true,
|
||||
token::Interpolated(nt) => may_be_ident(nt),
|
||||
token::Interpolated(nt) => nt_may_be_ident(nt),
|
||||
token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(kind))) => {
|
||||
may_be_ident(*kind)
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
NonterminalKind::Pat(pat_kind) => token.can_begin_pattern(pat_kind),
|
||||
|
|
|
|||
|
|
@ -1478,9 +1478,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
if segment_idx == 0 {
|
||||
if name == kw::SelfLower {
|
||||
let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
|
||||
module = Some(ModuleOrUniformRoot::Module(
|
||||
self.resolve_self(&mut ctxt, parent_scope.module),
|
||||
));
|
||||
let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
|
||||
if let Some(res) = self_mod.res() {
|
||||
record_segment_res(self, res);
|
||||
}
|
||||
module = Some(ModuleOrUniformRoot::Module(self_mod));
|
||||
continue;
|
||||
}
|
||||
if name == kw::PathRoot && ident.span.at_least_rust_2018() {
|
||||
|
|
@ -1497,7 +1499,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
}
|
||||
if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
|
||||
// `::a::b`, `crate::a::b` or `$crate::a::b`
|
||||
module = Some(ModuleOrUniformRoot::Module(self.resolve_crate_root(ident)));
|
||||
let crate_root = self.resolve_crate_root(ident);
|
||||
if let Some(res) = crate_root.res() {
|
||||
record_segment_res(self, res);
|
||||
}
|
||||
module = Some(ModuleOrUniformRoot::Module(crate_root));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,7 @@ impl OutputFilenames {
|
|||
self.with_directory_and_extension(&self.out_directory, extension)
|
||||
}
|
||||
|
||||
fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
|
||||
pub fn with_directory_and_extension(&self, directory: &PathBuf, extension: &str) -> PathBuf {
|
||||
let mut path = directory.join(&self.filestem);
|
||||
path.set_extension(extension);
|
||||
path
|
||||
|
|
|
|||
|
|
@ -1887,7 +1887,7 @@ options! {
|
|||
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||
"gather metadata statistics (default: no)"),
|
||||
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
||||
"stores metrics about the errors being emitted by rustc to disk"),
|
||||
"the directory metrics emitted by rustc are dumped into (implicitly enables default set of metrics)"),
|
||||
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
|
||||
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
||||
(default: no)"),
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
|
||||
// for a pre-z13 machine or using -mno-vx.
|
||||
// Reference: ELF Application Binary Interface s390x Supplement
|
||||
// https://github.com/IBM/s390x-abi
|
||||
|
||||
use crate::abi::call::{ArgAbi, FnAbi, Reg};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
|
||||
use crate::abi::{BackendRepr, HasDataLayout, TyAbiInterface};
|
||||
use crate::spec::HasTargetSpec;
|
||||
|
||||
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
|
||||
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
|
||||
let size = ret.layout.size;
|
||||
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
|
||||
return;
|
||||
}
|
||||
if !ret.layout.is_aggregate() && size.bits() <= 64 {
|
||||
ret.extend_integer_width_to(64);
|
||||
} else {
|
||||
ret.make_indirect();
|
||||
|
|
@ -32,19 +36,25 @@ where
|
|||
}
|
||||
return;
|
||||
}
|
||||
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
|
||||
|
||||
let size = arg.layout.size;
|
||||
if size.bits() <= 128 && arg.layout.is_single_vector_element(cx, size) {
|
||||
arg.cast_to(Reg { kind: RegKind::Vector, size });
|
||||
return;
|
||||
}
|
||||
if !arg.layout.is_aggregate() && size.bits() <= 64 {
|
||||
arg.extend_integer_width_to(64);
|
||||
return;
|
||||
}
|
||||
|
||||
if arg.layout.is_single_fp_element(cx) {
|
||||
match arg.layout.size.bytes() {
|
||||
match size.bytes() {
|
||||
4 => arg.cast_to(Reg::f32()),
|
||||
8 => arg.cast_to(Reg::f64()),
|
||||
_ => arg.make_indirect(),
|
||||
}
|
||||
} else {
|
||||
match arg.layout.size.bytes() {
|
||||
match size.bytes() {
|
||||
1 => arg.cast_to(Reg::i8()),
|
||||
2 => arg.cast_to(Reg::i16()),
|
||||
4 => arg.cast_to(Reg::i32()),
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
|
|||
base.endian = Endian::Big;
|
||||
// z10 is the oldest CPU supported by LLVM
|
||||
base.cpu = "z10".into();
|
||||
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
|
||||
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
|
||||
base.features = "-vector".into();
|
||||
base.max_atomic_width = Some(128);
|
||||
base.min_global_align = Some(16);
|
||||
base.stack_probes = StackProbeType::Inline;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
|
|||
base.endian = Endian::Big;
|
||||
// z10 is the oldest CPU supported by LLVM
|
||||
base.cpu = "z10".into();
|
||||
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
|
||||
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
|
||||
base.features = "-vector".into();
|
||||
base.max_atomic_width = Some(128);
|
||||
base.min_global_align = Some(16);
|
||||
base.static_position_independent_executables = true;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ use crate::spec::{
|
|||
pub(crate) fn target() -> Target {
|
||||
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
|
||||
let pre_link_args = LinkArgs::new();
|
||||
let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]);
|
||||
let post_link_args =
|
||||
TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-sWASM_BIGINT"]);
|
||||
|
||||
let opts = TargetOptions {
|
||||
os: "emscripten".into(),
|
||||
|
|
|
|||
|
|
@ -1075,93 +1075,110 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
|
||||
// Autoderef is useful here because sometimes we box callables, etc.
|
||||
let Some((def_id_or_name, output, inputs)) =
|
||||
(self.autoderef_steps)(found).into_iter().find_map(|(found, _)| {
|
||||
match *found.kind() {
|
||||
ty::FnPtr(sig_tys, _) => Some((
|
||||
DefIdOrName::Name("function pointer"),
|
||||
sig_tys.output(),
|
||||
sig_tys.inputs(),
|
||||
)),
|
||||
ty::FnDef(def_id, _) => {
|
||||
let fn_sig = found.fn_sig(self.tcx);
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
|
||||
}
|
||||
ty::Closure(def_id, args) => {
|
||||
let fn_sig = args.as_closure().sig();
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
fn_sig.output(),
|
||||
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
|
||||
))
|
||||
}
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
||||
self.tcx
|
||||
.item_super_predicates(def_id)
|
||||
.instantiate(self.tcx, args)
|
||||
.iter()
|
||||
.find_map(|pred| {
|
||||
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& self.tcx.is_lang_item(proj.projection_term.def_id,LangItem::FnOnceOutput)
|
||||
// args tuple will always be args[1]
|
||||
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
pred.kind().rebind(proj.term.expect_type()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::Dynamic(data, _, ty::Dyn) => {
|
||||
data.iter().find_map(|pred| {
|
||||
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
|
||||
(self.autoderef_steps)(found).into_iter().find_map(|(found, _)| match *found.kind() {
|
||||
ty::FnPtr(sig_tys, _) => Some((
|
||||
DefIdOrName::Name("function pointer"),
|
||||
sig_tys.output(),
|
||||
sig_tys.inputs(),
|
||||
)),
|
||||
ty::FnDef(def_id, _) => {
|
||||
let fn_sig = found.fn_sig(self.tcx);
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
|
||||
}
|
||||
ty::Closure(def_id, args) => {
|
||||
let fn_sig = args.as_closure().sig();
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
fn_sig.output(),
|
||||
fn_sig.inputs().map_bound(|inputs| inputs[0].tuple_fields().as_slice()),
|
||||
))
|
||||
}
|
||||
ty::CoroutineClosure(def_id, args) => {
|
||||
let sig_parts = args.as_coroutine_closure().coroutine_closure_sig();
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
sig_parts.map_bound(|sig| {
|
||||
sig.to_coroutine(
|
||||
self.tcx,
|
||||
args.as_coroutine_closure().parent_args(),
|
||||
// Just use infer vars here, since we don't really care
|
||||
// what these types are, just that we're returning a coroutine.
|
||||
self.next_ty_var(DUMMY_SP),
|
||||
self.tcx.coroutine_for_closure(def_id),
|
||||
self.next_ty_var(DUMMY_SP),
|
||||
)
|
||||
}),
|
||||
sig_parts.map_bound(|sig| sig.tupled_inputs_ty.tuple_fields().as_slice()),
|
||||
))
|
||||
}
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
|
||||
.tcx
|
||||
.item_super_predicates(def_id)
|
||||
.instantiate(self.tcx, args)
|
||||
.iter()
|
||||
.find_map(|pred| {
|
||||
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& self
|
||||
.tcx
|
||||
.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput)
|
||||
// args tuple will always be args[1]
|
||||
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
pred.kind().rebind(proj.term.expect_type()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}),
|
||||
ty::Dynamic(data, _, ty::Dyn) => data.iter().find_map(|pred| {
|
||||
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
|
||||
&& self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput)
|
||||
// for existential projection, args are shifted over by 1
|
||||
&& let ty::Tuple(args) = proj.args.type_at(0).kind()
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::Name("trait object"),
|
||||
pred.rebind(proj.term.expect_type()),
|
||||
pred.rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
{
|
||||
Some((
|
||||
DefIdOrName::Name("trait object"),
|
||||
pred.rebind(proj.term.expect_type()),
|
||||
pred.rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
ty::Param(param) => {
|
||||
let generics = self.tcx.generics_of(body_id);
|
||||
let name = if generics.count() > param.index as usize
|
||||
&& let def = generics.param_at(param.index as usize, self.tcx)
|
||||
&& matches!(def.kind, ty::GenericParamDefKind::Type { .. })
|
||||
&& def.name == param.name
|
||||
}),
|
||||
ty::Param(param) => {
|
||||
let generics = self.tcx.generics_of(body_id);
|
||||
let name = if generics.count() > param.index as usize
|
||||
&& let def = generics.param_at(param.index as usize, self.tcx)
|
||||
&& matches!(def.kind, ty::GenericParamDefKind::Type { .. })
|
||||
&& def.name == param.name
|
||||
{
|
||||
DefIdOrName::DefId(def.def_id)
|
||||
} else {
|
||||
DefIdOrName::Name("type parameter")
|
||||
};
|
||||
param_env.caller_bounds().iter().find_map(|pred| {
|
||||
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& self
|
||||
.tcx
|
||||
.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput)
|
||||
&& proj.projection_term.self_ty() == found
|
||||
// args tuple will always be args[1]
|
||||
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
|
||||
{
|
||||
DefIdOrName::DefId(def.def_id)
|
||||
Some((
|
||||
name,
|
||||
pred.kind().rebind(proj.term.expect_type()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
DefIdOrName::Name("type parameter")
|
||||
};
|
||||
param_env.caller_bounds().iter().find_map(|pred| {
|
||||
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
|
||||
&& self.tcx.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput)
|
||||
&& proj.projection_term.self_ty() == found
|
||||
// args tuple will always be args[1]
|
||||
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
|
||||
{
|
||||
Some((
|
||||
name,
|
||||
pred.kind().rebind(proj.term.expect_type()),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
else {
|
||||
return None;
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
|||
}
|
||||
// `T: ~const Trait` implies `T: ~const Supertrait`.
|
||||
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
|
||||
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||
elaboratable.child(
|
||||
trait_ref
|
||||
.to_host_effect_clause(cx, data.constness)
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ pub trait Interner:
|
|||
self,
|
||||
def_id: Self::DefId,
|
||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||
fn implied_const_bounds(
|
||||
fn explicit_implied_const_bounds(
|
||||
self,
|
||||
def_id: Self::DefId,
|
||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.161"
|
||||
version = "0.2.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
|
|||
addr2line = { version = "0.22.0", optional = true, default-features = false }
|
||||
|
||||
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
||||
libc = { version = "0.2.161", default-features = false, features = [
|
||||
libc = { version = "0.2.162", default-features = false, features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -1457,7 +1457,7 @@ impl Step for CodegenBackend {
|
|||
}
|
||||
let mut files = files.into_iter().filter(|f| {
|
||||
let filename = f.file_name().unwrap().to_str().unwrap();
|
||||
is_dylib(filename) && filename.contains("rustc_codegen_")
|
||||
is_dylib(f) && filename.contains("rustc_codegen_")
|
||||
});
|
||||
let codegen_backend = match files.next() {
|
||||
Some(f) => f,
|
||||
|
|
@ -1936,7 +1936,7 @@ impl Step for Assemble {
|
|||
let filename = f.file_name().into_string().unwrap();
|
||||
|
||||
let is_proc_macro = proc_macros.contains(&filename);
|
||||
let is_dylib_or_debug = is_dylib(&filename) || is_debug_info(&filename);
|
||||
let is_dylib_or_debug = is_dylib(&f.path()) || is_debug_info(&filename);
|
||||
|
||||
// If we link statically to stdlib, do not copy the libstd dynamic library file
|
||||
// FIXME: Also do this for Windows once incremental post-optimization stage0 tests
|
||||
|
|
@ -2089,7 +2089,7 @@ pub fn run_cargo(
|
|||
if filename.ends_with(".lib")
|
||||
|| filename.ends_with(".a")
|
||||
|| is_debug_info(&filename)
|
||||
|| is_dylib(&filename)
|
||||
|| is_dylib(Path::new(&*filename))
|
||||
{
|
||||
// Always keep native libraries, rust dylibs and debuginfo
|
||||
keep = true;
|
||||
|
|
@ -2189,7 +2189,7 @@ pub fn run_cargo(
|
|||
Some(triple) => triple.0.to_str().unwrap(),
|
||||
None => panic!("no output generated for {prefix:?} {extension:?}"),
|
||||
};
|
||||
if is_dylib(path_to_add) {
|
||||
if is_dylib(Path::new(path_to_add)) {
|
||||
let candidate = format!("{path_to_add}.lib");
|
||||
let candidate = PathBuf::from(candidate);
|
||||
if candidate.exists() {
|
||||
|
|
|
|||
|
|
@ -436,13 +436,10 @@ impl Step for Rustc {
|
|||
if libdir_relative.to_str() != Some("bin") {
|
||||
let libdir = builder.rustc_libdir(compiler);
|
||||
for entry in builder.read_dir(&libdir) {
|
||||
let name = entry.file_name();
|
||||
if let Some(s) = name.to_str() {
|
||||
if is_dylib(s) {
|
||||
// Don't use custom libdir here because ^lib/ will be resolved again
|
||||
// with installer
|
||||
builder.install(&entry.path(), &image.join("lib"), 0o644);
|
||||
}
|
||||
if is_dylib(&entry.path()) {
|
||||
// Don't use custom libdir here because ^lib/ will be resolved again
|
||||
// with installer
|
||||
builder.install(&entry.path(), &image.join("lib"), 0o644);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2949,8 +2949,7 @@ impl Step for RemoteCopyLibs {
|
|||
// Push all our dylibs to the emulator
|
||||
for f in t!(builder.sysroot_target_libdir(compiler, target).read_dir()) {
|
||||
let f = t!(f);
|
||||
let name = f.file_name().into_string().unwrap();
|
||||
if helpers::is_dylib(&name) {
|
||||
if helpers::is_dylib(&f.path()) {
|
||||
command(&tool).arg("push").arg(f.path()).run(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use std::time::{Instant, SystemTime, UNIX_EPOCH};
|
|||
use std::{env, fs, io, str};
|
||||
|
||||
use build_helper::util::fail;
|
||||
use object::read::archive::ArchiveFile;
|
||||
|
||||
use crate::LldMode;
|
||||
use crate::core::builder::Builder;
|
||||
|
|
@ -53,8 +54,27 @@ pub fn exe(name: &str, target: TargetSelection) -> String {
|
|||
}
|
||||
|
||||
/// Returns `true` if the file name given looks like a dynamic library.
|
||||
pub fn is_dylib(name: &str) -> bool {
|
||||
name.ends_with(".dylib") || name.ends_with(".so") || name.ends_with(".dll")
|
||||
pub fn is_dylib(path: &Path) -> bool {
|
||||
path.extension().and_then(|ext| ext.to_str()).map_or(false, |ext| {
|
||||
ext == "dylib" || ext == "so" || ext == "dll" || (ext == "a" && is_aix_shared_archive(path))
|
||||
})
|
||||
}
|
||||
|
||||
fn is_aix_shared_archive(path: &Path) -> bool {
|
||||
// FIXME(#133268): reading the entire file as &[u8] into memory seems excessive
|
||||
// look into either mmap it or use the ReadCache
|
||||
let data = match fs::read(path) {
|
||||
Ok(data) => data,
|
||||
Err(_) => return false,
|
||||
};
|
||||
let file = match ArchiveFile::parse(&*data) {
|
||||
Ok(file) => file,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
file.members()
|
||||
.filter_map(Result::ok)
|
||||
.any(|entry| String::from_utf8_lossy(entry.name()).contains(".so"))
|
||||
}
|
||||
|
||||
/// Returns `true` if the file name given looks like a debug info file
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
|
|||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo"
|
||||
|
||||
if [ "$DEPLOY_ALT" != "" ]; then
|
||||
if [ "$DEPLOY_ALT" != "" ] && isLinux; then
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level=2"
|
||||
else
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ unsafe {
|
|||
}
|
||||
```
|
||||
|
||||
The block must have unit type or diverge.
|
||||
The block must have unit type or diverge. The block starts a new safety context,
|
||||
so despite outer `unsafe`, you need extra unsafe to perform unsafe operations
|
||||
within `label <block>`.
|
||||
|
||||
When `label <block>` is used together with `noreturn` option, it means that the
|
||||
assembly will not fallthrough. It's allowed to jump to a label within the
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b35599be758613448201a49f4b8c7ebfba5558ac
|
||||
Subproject commit 104d0d16c3c7c3fef2435fef6efb2d57b70fff73
|
||||
|
|
@ -153,7 +153,7 @@ case $HOST_TARGET in
|
|||
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
|
||||
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
|
||||
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
# TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
|
||||
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread
|
||||
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
|
||||
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2d0ea7956c45de6e421fd579e2ded27be405dec6
|
||||
5d3c6ee9b34989595d2a72b79e61ca37e949d757
|
||||
|
|
|
|||
|
|
@ -620,7 +620,7 @@ fn delim_token_to_str(
|
|||
("{ ", " }")
|
||||
}
|
||||
}
|
||||
Delimiter::Invisible => unreachable!(),
|
||||
Delimiter::Invisible(_) => unreachable!(),
|
||||
};
|
||||
if use_multiple_lines {
|
||||
let indent_str = shape.indent.to_string_with_newline(context.config);
|
||||
|
|
|
|||
322
tests/assembly/s390x-vector-abi.rs
Normal file
322
tests/assembly/s390x-vector-abi.rs
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
//@ revisions: z10 z10_vector z13 z13_no_vector
|
||||
// ignore-tidy-linelength
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: -O -Z merge-functions=disabled
|
||||
//@[z10] compile-flags: --target s390x-unknown-linux-gnu --cfg no_vector
|
||||
//@[z10] needs-llvm-components: systemz
|
||||
//@[z10_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
|
||||
//@[z10_vector] needs-llvm-components: systemz
|
||||
//@[z13] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13
|
||||
//@[z13] needs-llvm-components: systemz
|
||||
//@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector --cfg no_vector
|
||||
//@[z13_no_vector] needs-llvm-components: systemz
|
||||
|
||||
#![feature(no_core, lang_items, repr_simd, s390x_target_feature)]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
// Cases where vector feature is disabled are rejected.
|
||||
// See tests/ui/simd-abi-checks-s390x.rs for test for them.
|
||||
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
#[lang = "freeze"]
|
||||
pub trait Freeze {}
|
||||
|
||||
impl<T: Copy, const N: usize> Copy for [T; N] {}
|
||||
|
||||
#[lang = "phantom_data"]
|
||||
pub struct PhantomData<T: ?Sized>;
|
||||
impl<T: ?Sized> Copy for PhantomData<T> {}
|
||||
|
||||
#[repr(simd)]
|
||||
pub struct i8x8([i8; 8]);
|
||||
#[repr(simd)]
|
||||
pub struct i8x16([i8; 16]);
|
||||
#[repr(simd)]
|
||||
pub struct i8x32([i8; 32]);
|
||||
#[repr(C)]
|
||||
pub struct Wrapper<T>(T);
|
||||
#[repr(C, align(16))]
|
||||
pub struct WrapperAlign16<T>(T);
|
||||
#[repr(C)]
|
||||
pub struct WrapperWithZst<T>(T, PhantomData<()>);
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentWrapper<T>(T);
|
||||
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i64 {}
|
||||
impl Copy for i8x8 {}
|
||||
impl Copy for i8x16 {}
|
||||
impl Copy for i8x32 {}
|
||||
impl<T: Copy> Copy for Wrapper<T> {}
|
||||
impl<T: Copy> Copy for WrapperAlign16<T> {}
|
||||
impl<T: Copy> Copy for WrapperWithZst<T> {}
|
||||
impl<T: Copy> Copy for TransparentWrapper<T> {}
|
||||
|
||||
// CHECK-LABEL: vector_ret_small:
|
||||
// CHECK: vlrepg %v24, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_ret:
|
||||
// CHECK: vl %v24, 0(%r2), 3
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_ret_large:
|
||||
// z10: vl %v0, 16(%r3), 4
|
||||
// z10-NEXT: vl %v1, 0(%r3), 4
|
||||
// z10-NEXT: vst %v0, 16(%r2), 4
|
||||
// z10-NEXT: vst %v1, 0(%r2), 4
|
||||
// z10-NEXT: br %r14
|
||||
// z13: vl %v0, 0(%r3), 4
|
||||
// z13-NEXT: vl %v1, 16(%r3), 4
|
||||
// z13-NEXT: vst %v1, 16(%r2), 4
|
||||
// z13-NEXT: vst %v0, 0(%r2), 4
|
||||
// z13-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_ret_large(x: &i8x32) -> i8x32 {
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_wrapper_ret_small:
|
||||
// CHECK: mvc 0(8,%r2), 0(%r3)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_ret_small(x: &Wrapper<i8x8>) -> Wrapper<i8x8> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_ret:
|
||||
// CHECK: mvc 0(16,%r2), 0(%r3)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_ret(x: &Wrapper<i8x16>) -> Wrapper<i8x16> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_ret_large:
|
||||
// z10: vl %v0, 16(%r3), 4
|
||||
// z10-NEXT: vl %v1, 0(%r3), 4
|
||||
// z10-NEXT: vst %v0, 16(%r2), 4
|
||||
// z10-NEXT: vst %v1, 0(%r2), 4
|
||||
// z10-NEXT: br %r14
|
||||
// z13: vl %v0, 16(%r3), 4
|
||||
// z13-NEXT: vst %v0, 16(%r2), 4
|
||||
// z13-NEXT: vl %v0, 0(%r3), 4
|
||||
// z13-NEXT: vst %v0, 0(%r2), 4
|
||||
// z13-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_ret_large(x: &Wrapper<i8x32>) -> Wrapper<i8x32> {
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_wrapper_padding_ret:
|
||||
// CHECK: mvc 0(16,%r2), 0(%r3)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_padding_ret(x: &WrapperAlign16<i8x8>) -> WrapperAlign16<i8x8> {
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_ret_small:
|
||||
// CHECK: mvc 0(8,%r2), 0(%r3)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_ret_small(
|
||||
x: &WrapperWithZst<i8x8>,
|
||||
) -> WrapperWithZst<i8x8> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_ret:
|
||||
// CHECK: mvc 0(16,%r2), 0(%r3)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_ret(
|
||||
x: &WrapperWithZst<i8x16>,
|
||||
) -> WrapperWithZst<i8x16> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_ret_large:
|
||||
// z10: vl %v0, 16(%r3), 4
|
||||
// z10-NEXT: vl %v1, 0(%r3), 4
|
||||
// z10-NEXT: vst %v0, 16(%r2), 4
|
||||
// z10-NEXT: vst %v1, 0(%r2), 4
|
||||
// z10-NEXT: br %r14
|
||||
// z13: vl %v0, 16(%r3), 4
|
||||
// z13-NEXT: vst %v0, 16(%r2), 4
|
||||
// z13-NEXT: vl %v0, 0(%r3), 4
|
||||
// z13-NEXT: vst %v0, 0(%r2), 4
|
||||
// z13-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_ret_large(
|
||||
x: &WrapperWithZst<i8x32>,
|
||||
) -> WrapperWithZst<i8x32> {
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_transparent_wrapper_ret_small:
|
||||
// CHECK: vlrepg %v24, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_ret_small(
|
||||
x: &TransparentWrapper<i8x8>,
|
||||
) -> TransparentWrapper<i8x8> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_transparent_wrapper_ret:
|
||||
// CHECK: vl %v24, 0(%r2), 3
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_ret(
|
||||
x: &TransparentWrapper<i8x16>,
|
||||
) -> TransparentWrapper<i8x16> {
|
||||
*x
|
||||
}
|
||||
// CHECK-LABEL: vector_transparent_wrapper_ret_large:
|
||||
// z10: vl %v0, 16(%r3), 4
|
||||
// z10-NEXT: vl %v1, 0(%r3), 4
|
||||
// z10-NEXT: vst %v0, 16(%r2), 4
|
||||
// z10-NEXT: vst %v1, 0(%r2), 4
|
||||
// z10-NEXT: br %r14
|
||||
// z13: vl %v0, 0(%r3), 4
|
||||
// z13-NEXT: vl %v1, 16(%r3), 4
|
||||
// z13-NEXT: vst %v1, 16(%r2), 4
|
||||
// z13-NEXT: vst %v0, 0(%r2), 4
|
||||
// z13-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_ret_large(
|
||||
x: &TransparentWrapper<i8x32>,
|
||||
) -> TransparentWrapper<i8x32> {
|
||||
*x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_arg_small:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_arg_small(x: i8x8) -> i64 {
|
||||
unsafe { *(&x as *const i8x8 as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_arg:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_arg(x: i8x16) -> i64 {
|
||||
unsafe { *(&x as *const i8x16 as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_arg_large:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_arg_large(x: i8x32) -> i64 {
|
||||
unsafe { *(&x as *const i8x32 as *const i64) }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_wrapper_arg_small:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
|
||||
unsafe { *(&x as *const Wrapper<i8x8> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_arg:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
|
||||
unsafe { *(&x as *const Wrapper<i8x16> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_arg_large:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_arg_large(x: Wrapper<i8x32>) -> i64 {
|
||||
unsafe { *(&x as *const Wrapper<i8x32> as *const i64) }
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust/pull/131586#discussion_r1837071121
|
||||
// CHECK-LABEL: vector_wrapper_padding_arg:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_padding_arg(x: WrapperAlign16<i8x8>) -> i64 {
|
||||
unsafe { *(&x as *const WrapperAlign16<i8x8> as *const i64) }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_arg_small:
|
||||
// CHECK: .cfi_startproc
|
||||
// CHECK-NOT: vlgvg
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_arg_small(x: WrapperWithZst<i8x8>) -> i64 {
|
||||
unsafe { *(&x as *const WrapperWithZst<i8x8> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_arg:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_arg(x: WrapperWithZst<i8x16>) -> i64 {
|
||||
unsafe { *(&x as *const WrapperWithZst<i8x16> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_wrapper_with_zst_arg_large:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_wrapper_with_zst_arg_large(x: WrapperWithZst<i8x32>) -> i64 {
|
||||
unsafe { *(&x as *const WrapperWithZst<i8x32> as *const i64) }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: vector_transparent_wrapper_arg_small:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x8> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_transparent_wrapper_arg:
|
||||
// CHECK: vlgvg %r2, %v24, 0
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x16> as *const i64) }
|
||||
}
|
||||
// CHECK-LABEL: vector_transparent_wrapper_arg_large:
|
||||
// CHECK: lg %r2, 0(%r2)
|
||||
// CHECK-NEXT: br %r14
|
||||
#[cfg_attr(no_vector, target_feature(enable = "vector"))]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn vector_transparent_wrapper_arg_large(x: TransparentWrapper<i8x32>) -> i64 {
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x32> as *const i64) }
|
||||
}
|
||||
9
tests/run-make/unstable-feature-usage-metrics/lib.rs
Normal file
9
tests/run-make/unstable-feature-usage-metrics/lib.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#![feature(ascii_char)] // random lib feature
|
||||
#![feature(box_patterns)] // random lang feature
|
||||
|
||||
// picked arbitrary unstable features, just need a random lib and lang feature, ideally ones that
|
||||
// won't be stabilized any time soon so we don't have to update this test
|
||||
|
||||
fn main() {
|
||||
println!("foobar");
|
||||
}
|
||||
87
tests/run-make/unstable-feature-usage-metrics/rmake.rs
Normal file
87
tests/run-make/unstable-feature-usage-metrics/rmake.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//! This test checks if unstable feature usage metric dump files `unstable-feature-usage*.json` work
|
||||
//! as expected.
|
||||
//!
|
||||
//! - Basic sanity checks on a default ICE dump.
|
||||
//!
|
||||
//! See <https://github.com/rust-lang/rust/issues/129485>.
|
||||
//!
|
||||
//! # Test history
|
||||
//!
|
||||
//! - forked from dump-ice-to-disk test, which has flakeyness issues on i686-mingw, I'm assuming
|
||||
//! those will be present in this test as well on the same platform
|
||||
|
||||
//@ ignore-windows
|
||||
//FIXME(#128911): still flakey on i686-mingw.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use run_make_support::rfs::create_dir_all;
|
||||
use run_make_support::{
|
||||
cwd, filename_contains, has_extension, rfs, run_in_tmpdir, rustc, serde_json,
|
||||
shallow_find_files,
|
||||
};
|
||||
|
||||
fn find_feature_usage_metrics<P: AsRef<Path>>(dir: P) -> Vec<PathBuf> {
|
||||
shallow_find_files(dir, |path| {
|
||||
if filename_contains(path, "unstable_feature_usage") && has_extension(path, "json") {
|
||||
true
|
||||
} else {
|
||||
dbg!(path);
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_metrics_dump();
|
||||
test_metrics_errors();
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn test_metrics_dump() {
|
||||
run_in_tmpdir(|| {
|
||||
let metrics_dir = cwd().join("metrics");
|
||||
create_dir_all(&metrics_dir);
|
||||
rustc()
|
||||
.input("lib.rs")
|
||||
.env("RUST_BACKTRACE", "short")
|
||||
.arg(format!("-Zmetrics-dir={}", metrics_dir.display()))
|
||||
.run();
|
||||
let mut metrics = find_feature_usage_metrics(&metrics_dir);
|
||||
let json_path =
|
||||
metrics.pop().expect("there should be one metrics file in the output directory");
|
||||
|
||||
// After the `pop` above, there should be no files left.
|
||||
assert!(
|
||||
metrics.is_empty(),
|
||||
"there should be no more than one metrics file in the output directory"
|
||||
);
|
||||
|
||||
let message = rfs::read_to_string(json_path);
|
||||
let parsed: serde_json::Value =
|
||||
serde_json::from_str(&message).expect("metrics should be dumped as json");
|
||||
let expected = serde_json::json!(
|
||||
{
|
||||
"lib_features":[{"symbol":"ascii_char"}],
|
||||
"lang_features":[{"symbol":"box_patterns","since":null}]
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(expected, parsed);
|
||||
});
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn test_metrics_errors() {
|
||||
run_in_tmpdir(|| {
|
||||
rustc()
|
||||
.input("lib.rs")
|
||||
.env("RUST_BACKTRACE", "short")
|
||||
.arg("-Zmetrics-dir=invaliddirectorythatdefinitelydoesntexist")
|
||||
.run_fail()
|
||||
.assert_stderr_contains(
|
||||
"error: cannot dump feature usage metrics: No such file or directory",
|
||||
)
|
||||
.assert_stdout_not_contains("internal compiler error");
|
||||
});
|
||||
}
|
||||
23
tests/ui/asm/x86_64/goto-block-safe.rs
Normal file
23
tests/ui/asm/x86_64/goto-block-safe.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//@ only-x86_64
|
||||
//@ needs-asm-support
|
||||
|
||||
#![deny(unreachable_code)]
|
||||
#![feature(asm_goto)]
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn goto_fallthough() {
|
||||
unsafe {
|
||||
asm!(
|
||||
"/* {} */",
|
||||
label {
|
||||
core::hint::unreachable_unchecked();
|
||||
//~^ ERROR [E0133]
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
goto_fallthough();
|
||||
}
|
||||
14
tests/ui/asm/x86_64/goto-block-safe.stderr
Normal file
14
tests/ui/asm/x86_64/goto-block-safe.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error[E0133]: call to unsafe function `unreachable_unchecked` is unsafe and requires unsafe function or block
|
||||
--> $DIR/goto-block-safe.rs:14:17
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ items do not inherit unsafety from separate enclosing items
|
||||
...
|
||||
LL | core::hint::unreachable_unchecked();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
||||
7
tests/ui/closures/correct-args-on-call-suggestion.rs
Normal file
7
tests/ui/closures/correct-args-on-call-suggestion.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Ensure we give the right args when we suggest calling a closure.
|
||||
|
||||
fn main() {
|
||||
let x = |a: i32, b: i32| a + b;
|
||||
let y: i32 = x;
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
20
tests/ui/closures/correct-args-on-call-suggestion.stderr
Normal file
20
tests/ui/closures/correct-args-on-call-suggestion.stderr
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/correct-args-on-call-suggestion.rs:5:18
|
||||
|
|
||||
LL | let x = |a: i32, b: i32| a + b;
|
||||
| ---------------- the found closure
|
||||
LL | let y: i32 = x;
|
||||
| --- ^ expected `i32`, found closure
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found closure `{closure@$DIR/correct-args-on-call-suggestion.rs:4:13: 4:29}`
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | let y: i32 = x(/* i32 */, /* i32 */);
|
||||
| ++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -7,7 +7,7 @@ LL | struct Obj<F> where F: FnMut() -> u32 {
|
|||
LL | o.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `closure`, surround the field access with parentheses
|
||||
help: to call the closure stored in `closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (o.closure)();
|
||||
| + +
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | struct Obj<F> where F: FnOnce() -> u32 {
|
|||
LL | o_closure.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `closure`, surround the field access with parentheses
|
||||
help: to call the closure stored in `closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (o_closure.closure)();
|
||||
| + +
|
||||
|
|
@ -46,7 +46,7 @@ LL | struct BoxedObj {
|
|||
LL | boxed_fn.boxed_closure();
|
||||
| ^^^^^^^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `boxed_closure`, surround the field access with parentheses
|
||||
help: to call the trait object stored in `boxed_closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (boxed_fn.boxed_closure)();
|
||||
| + +
|
||||
|
|
@ -60,7 +60,7 @@ LL | struct BoxedObj {
|
|||
LL | boxed_closure.boxed_closure();
|
||||
| ^^^^^^^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `boxed_closure`, surround the field access with parentheses
|
||||
help: to call the trait object stored in `boxed_closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (boxed_closure.boxed_closure)();
|
||||
| + +
|
||||
|
|
@ -99,7 +99,7 @@ LL | struct Obj<F> where F: FnOnce() -> u32 {
|
|||
LL | check_expression().closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `closure`, surround the field access with parentheses
|
||||
help: to call the trait object stored in `closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (check_expression().closure)();
|
||||
| + +
|
||||
|
|
@ -113,7 +113,7 @@ LL | struct FuncContainer {
|
|||
LL | (*self.container).f1(1);
|
||||
| ^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `f1`, surround the field access with parentheses
|
||||
help: to call the function pointer stored in `f1`, surround the field access with parentheses
|
||||
|
|
||||
LL | ((*self.container).f1)(1);
|
||||
| + +
|
||||
|
|
@ -127,7 +127,7 @@ LL | struct FuncContainer {
|
|||
LL | (*self.container).f2(1);
|
||||
| ^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `f2`, surround the field access with parentheses
|
||||
help: to call the function pointer stored in `f2`, surround the field access with parentheses
|
||||
|
|
||||
LL | ((*self.container).f2)(1);
|
||||
| + +
|
||||
|
|
@ -141,7 +141,7 @@ LL | struct FuncContainer {
|
|||
LL | (*self.container).f3(1);
|
||||
| ^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `f3`, surround the field access with parentheses
|
||||
help: to call the function pointer stored in `f3`, surround the field access with parentheses
|
||||
|
|
||||
LL | ((*self.container).f3)(1);
|
||||
| + +
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | struct Example {
|
|||
LL | demo.example(1);
|
||||
| ^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `example`, surround the field access with parentheses
|
||||
help: to call the trait object stored in `example`, surround the field access with parentheses
|
||||
|
|
||||
LL | (demo.example)(1);
|
||||
| + +
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error[E0599]: no method named `closure` found for reference `&Obj<{closure@$DIR/
|
|||
LL | p.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `closure`, surround the field access with parentheses
|
||||
help: to call the closure stored in `closure`, surround the field access with parentheses
|
||||
|
|
||||
LL | (p.closure)();
|
||||
| + +
|
||||
|
|
@ -19,7 +19,7 @@ error[E0599]: no method named `fn_ptr` found for reference `&&Obj<{closure@$DIR/
|
|||
LL | q.fn_ptr();
|
||||
| ^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `fn_ptr`, surround the field access with parentheses
|
||||
help: to call the function pointer stored in `fn_ptr`, surround the field access with parentheses
|
||||
|
|
||||
LL | (q.fn_ptr)();
|
||||
| + +
|
||||
|
|
@ -30,7 +30,7 @@ error[E0599]: no method named `c_fn_ptr` found for reference `&D` in the current
|
|||
LL | s.c_fn_ptr();
|
||||
| ^^^^^^^^ field, not a method
|
||||
|
|
||||
help: to call the function stored in `c_fn_ptr`, surround the field access with parentheses
|
||||
help: to call the function pointer stored in `c_fn_ptr`, surround the field access with parentheses
|
||||
|
|
||||
LL | (s.c_fn_ptr)();
|
||||
| + +
|
||||
|
|
|
|||
18
tests/ui/generics/generics-on-self-mod-segment.rs
Normal file
18
tests/ui/generics/generics-on-self-mod-segment.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
struct Ty;
|
||||
|
||||
fn self_(_: self::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
fn crate_(_: crate::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
macro_rules! dollar_crate {
|
||||
() => {
|
||||
fn dollar_crate_(_: $crate::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
}
|
||||
}
|
||||
|
||||
dollar_crate!();
|
||||
|
||||
fn main() {}
|
||||
32
tests/ui/generics/generics-on-self-mod-segment.stderr
Normal file
32
tests/ui/generics/generics-on-self-mod-segment.stderr
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:3:20
|
||||
|
|
||||
LL | fn self_(_: self::<i32>::Ty) {}
|
||||
| ---- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:6:22
|
||||
|
|
||||
LL | fn crate_(_: crate::<i32>::Ty) {}
|
||||
| ----- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:11:38
|
||||
|
|
||||
LL | fn dollar_crate_(_: $crate::<i32>::Ty) {}
|
||||
| ------ ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
...
|
||||
LL | dollar_crate!();
|
||||
| --------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0109`.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0767]: use of unreachable label `'a`
|
||||
--> $DIR/cross_const_control_flow.rs:9:25
|
||||
--> $DIR/cross-const-control-flow-125846.rs:9:25
|
||||
|
|
||||
LL | 'a: { const { break 'a } }
|
||||
| -- ^^ unreachable label `'a`
|
||||
|
|
@ -9,7 +9,7 @@ LL | 'a: { const { break 'a } }
|
|||
= note: labels are unreachable through functions, closures, async blocks and modules
|
||||
|
||||
error[E0767]: use of unreachable label `'a`
|
||||
--> $DIR/cross_const_control_flow.rs:22:28
|
||||
--> $DIR/cross-const-control-flow-125846.rs:22:28
|
||||
|
|
||||
LL | 'a: { const { continue 'a } }
|
||||
| -- ^^ unreachable label `'a`
|
||||
|
|
@ -19,7 +19,7 @@ LL | 'a: { const { continue 'a } }
|
|||
= note: labels are unreachable through functions, closures, async blocks and modules
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/cross_const_control_flow.rs:41:14
|
||||
--> $DIR/cross-const-control-flow-125846.rs:41:14
|
||||
|
|
||||
LL | const { &x };
|
||||
| ^ non-constant value
|
||||
|
|
@ -30,7 +30,7 @@ LL | const x: /* Type */ = 1;
|
|||
| ~~~~~ ++++++++++++
|
||||
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/cross_const_control_flow.rs:35:22
|
||||
--> $DIR/cross-const-control-flow-125846.rs:35:22
|
||||
|
|
||||
LL | const { async {}.await }
|
||||
| -----------^^^^^--
|
||||
|
|
@ -39,31 +39,31 @@ LL | const { async {}.await }
|
|||
| this is not `async`
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/cross_const_control_flow.rs:9:19
|
||||
--> $DIR/cross-const-control-flow-125846.rs:9:19
|
||||
|
|
||||
LL | 'a: { const { break 'a } }
|
||||
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `break` outside of a loop or labeled block
|
||||
--> $DIR/cross_const_control_flow.rs:16:17
|
||||
--> $DIR/cross-const-control-flow-125846.rs:16:17
|
||||
|
|
||||
LL | const { break }
|
||||
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||
|
||||
error[E0268]: `continue` outside of a loop
|
||||
--> $DIR/cross_const_control_flow.rs:22:19
|
||||
--> $DIR/cross-const-control-flow-125846.rs:22:19
|
||||
|
|
||||
LL | 'a: { const { continue 'a } }
|
||||
| ^^^^^^^^^^^ cannot `continue` outside of a loop
|
||||
|
||||
error[E0268]: `continue` outside of a loop
|
||||
--> $DIR/cross_const_control_flow.rs:29:17
|
||||
--> $DIR/cross-const-control-flow-125846.rs:29:17
|
||||
|
|
||||
LL | const { continue }
|
||||
| ^^^^^^^^ cannot `continue` outside of a loop
|
||||
|
||||
error[E0572]: return statement outside of function body
|
||||
--> $DIR/cross_const_control_flow.rs:4:13
|
||||
--> $DIR/cross-const-control-flow-125846.rs:4:13
|
||||
|
|
||||
LL | / fn foo() {
|
||||
LL | | const { return }
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/referencing_local_variables.rs:2:13
|
||||
--> $DIR/referencing-local-variables.rs:2:13
|
||||
|
|
||||
LL | const fn test_me<T>(a: usize) -> usize {
|
||||
| - this would need to be a `const`
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0381]: used binding `x` isn't initialized
|
||||
--> $DIR/uninit_local.rs:4:15
|
||||
--> $DIR/uninit-local.rs:4:15
|
||||
|
|
||||
LL | let x: bool;
|
||||
| - binding declared here but left uninitialized
|
||||
174
tests/ui/simd-abi-checks-s390x.rs
Normal file
174
tests/ui/simd-abi-checks-s390x.rs
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
//@ revisions: z10 z13_no_vector z13_soft_float
|
||||
//@ build-fail
|
||||
//@[z10] compile-flags: --target s390x-unknown-linux-gnu
|
||||
//@[z10] needs-llvm-components: systemz
|
||||
//@[z13_no_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector
|
||||
//@[z13_no_vector] needs-llvm-components: systemz
|
||||
// FIXME: +soft-float itself doesn't set -vector
|
||||
//@[z13_soft_float] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float
|
||||
//@[z13_soft_float] needs-llvm-components: systemz
|
||||
|
||||
#![feature(no_core, lang_items, repr_simd, s390x_target_feature)]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
#![allow(non_camel_case_types, improper_ctypes_definitions)]
|
||||
#![deny(abi_unsupported_vector_types)]
|
||||
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
#[lang = "freeze"]
|
||||
pub trait Freeze {}
|
||||
|
||||
impl<T: Copy, const N: usize> Copy for [T; N] {}
|
||||
|
||||
#[repr(simd)]
|
||||
pub struct i8x8([i8; 8]);
|
||||
#[repr(simd)]
|
||||
pub struct i8x16([i8; 16]);
|
||||
#[repr(simd)]
|
||||
pub struct i8x32([i8; 32]);
|
||||
#[repr(C)]
|
||||
pub struct Wrapper<T>(T);
|
||||
#[repr(transparent)]
|
||||
pub struct TransparentWrapper<T>(T);
|
||||
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i64 {}
|
||||
impl Copy for i8x8 {}
|
||||
impl Copy for i8x16 {}
|
||||
impl Copy for i8x32 {}
|
||||
impl<T: Copy> Copy for Wrapper<T> {}
|
||||
impl<T: Copy> Copy for TransparentWrapper<T> {}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_ret_large(x: &i8x32) -> i8x32 {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[target_feature(enable = "vector")]
|
||||
unsafe extern "C" fn vector_ret_target_feature_small(x: &i8x8) -> i8x8 {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
#[target_feature(enable = "vector")]
|
||||
unsafe extern "C" fn vector_target_feature_ret(x: &i8x16) -> i8x16 {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
#[target_feature(enable = "vector")]
|
||||
unsafe extern "C" fn vector_ret_target_feature_large(x: &i8x32) -> i8x32 {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_ret_small(x: &Wrapper<i8x8>) -> Wrapper<i8x8> {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_ret(x: &Wrapper<i8x16>) -> Wrapper<i8x16> {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_ret_large(x: &Wrapper<i8x32>) -> Wrapper<i8x32> {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_ret_small(
|
||||
x: &TransparentWrapper<i8x8>,
|
||||
) -> TransparentWrapper<i8x8> {
|
||||
//~^^^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^^^ WARN this was previously accepted
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_ret(
|
||||
x: &TransparentWrapper<i8x16>,
|
||||
) -> TransparentWrapper<i8x16> {
|
||||
//~^^^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^^^ WARN this was previously accepted
|
||||
*x
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_ret_large(
|
||||
x: &TransparentWrapper<i8x32>,
|
||||
) -> TransparentWrapper<i8x32> {
|
||||
// Ok
|
||||
*x
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_arg_small(x: i8x8) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const i8x8 as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_arg(x: i8x16) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const i8x16 as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_arg_large(x: i8x32) -> i64 {
|
||||
// Ok
|
||||
unsafe { *(&x as *const i8x32 as *const i64) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const Wrapper<i8x8> as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const Wrapper<i8x16> as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_wrapper_arg_large(x: Wrapper<i8x32>) -> i64 {
|
||||
// Ok
|
||||
unsafe { *(&x as *const Wrapper<i8x32> as *const i64) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x8> as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
|
||||
//~^ ERROR this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
//~^^ WARN this was previously accepted
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x16> as *const i64) }
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn vector_transparent_wrapper_arg_large(x: TransparentWrapper<i8x32>) -> i64 {
|
||||
// Ok
|
||||
unsafe { *(&x as *const TransparentWrapper<i8x32> as *const i64) }
|
||||
}
|
||||
111
tests/ui/simd-abi-checks-s390x.z10.stderr
Normal file
111
tests/ui/simd-abi-checks-s390x.z10.stderr
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
note: the lint level is defined here
|
||||
--> $DIR/simd-abi-checks-s390x.rs:15:9
|
||||
|
|
||||
LL | #![deny(abi_unsupported_vector_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:52:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
|
||||
LL | | x: &TransparentWrapper<i8x8>,
|
||||
LL | | ) -> TransparentWrapper<i8x8> {
|
||||
| |_____________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:107:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret(
|
||||
LL | | x: &TransparentWrapper<i8x16>,
|
||||
LL | | ) -> TransparentWrapper<i8x16> {
|
||||
| |______________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:123:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:129:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:141:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:147:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:159:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:165:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
111
tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr
Normal file
111
tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
note: the lint level is defined here
|
||||
--> $DIR/simd-abi-checks-s390x.rs:15:9
|
||||
|
|
||||
LL | #![deny(abi_unsupported_vector_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:52:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
|
||||
LL | | x: &TransparentWrapper<i8x8>,
|
||||
LL | | ) -> TransparentWrapper<i8x8> {
|
||||
| |_____________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:107:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret(
|
||||
LL | | x: &TransparentWrapper<i8x16>,
|
||||
LL | | ) -> TransparentWrapper<i8x16> {
|
||||
| |______________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:123:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:129:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:141:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:147:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:159:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:165:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
111
tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr
Normal file
111
tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:46:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
note: the lint level is defined here
|
||||
--> $DIR/simd-abi-checks-s390x.rs:15:9
|
||||
|
|
||||
LL | #![deny(abi_unsupported_vector_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:52:1
|
||||
|
|
||||
LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:99:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret_small(
|
||||
LL | | x: &TransparentWrapper<i8x8>,
|
||||
LL | | ) -> TransparentWrapper<i8x8> {
|
||||
| |_____________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:107:1
|
||||
|
|
||||
LL | / extern "C" fn vector_transparent_wrapper_ret(
|
||||
LL | | x: &TransparentWrapper<i8x16>,
|
||||
LL | | ) -> TransparentWrapper<i8x16> {
|
||||
| |______________________________^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:123:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:129:1
|
||||
|
|
||||
LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:141:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:147:1
|
||||
|
|
||||
LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:159:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `vector` target feature, which is not enabled
|
||||
--> $DIR/simd-abi-checks-s390x.rs:165:1
|
||||
|
|
||||
LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
|
||||
= help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
|
|
@ -31,6 +31,10 @@ note: required by a bound in `bar`
|
|||
|
|
||||
LL | fn bar(f: impl Future<Output=()>) {}
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `bar`
|
||||
help: use parentheses to call this closure
|
||||
|
|
||||
LL | bar(async_closure());
|
||||
| ++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
trait Trait {}
|
||||
|
||||
fn test<T: ?self::<i32>::Trait>() {}
|
||||
//~^ ERROR type arguments are not allowed on this type
|
||||
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
|
||||
//~| WARN relaxing a default bound only does something for `?Sized`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
|
|||
LL | fn test<T: ?self::<i32>::Trait>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0109]: type arguments are not allowed on this type
|
||||
error[E0109]: type arguments are not allowed on module `maybe_bound_has_path_args`
|
||||
--> $DIR/maybe-bound-has-path-args.rs:3:20
|
||||
|
|
||||
LL | fn test<T: ?self::<i32>::Trait>() {}
|
||||
| ---- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on this type
|
||||
| not allowed on module `maybe_bound_has_path_args`
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue