Merge from rustc

This commit is contained in:
The rustc-dev-guide Cronjob Bot
2025-05-15 09:46:22 +00:00
455 changed files with 4583 additions and 2765 deletions
+27 -57
View File
@@ -4,19 +4,13 @@ version = 4
[[package]]
name = "addr2line"
version = "0.21.0"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli 0.28.1",
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler2"
version = "2.0.0"
@@ -168,7 +162,7 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
dependencies = [
"object 0.36.7",
"object",
]
[[package]]
@@ -233,17 +227,17 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
version = "0.3.71"
version = "0.3.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide 0.7.4",
"object 0.32.2",
"miniz_oxide",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
]
[[package]]
@@ -780,7 +774,7 @@ dependencies = [
"itertools",
"leb128",
"md-5",
"miniz_oxide 0.7.4",
"miniz_oxide",
"regex",
"rustc-demangle",
]
@@ -849,9 +843,9 @@ dependencies = [
[[package]]
name = "ctrlc"
version = "3.4.6"
version = "3.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c"
checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
dependencies = [
"nix",
"windows-sys 0.59.0",
@@ -1220,7 +1214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.8",
"miniz_oxide",
]
[[package]]
@@ -1453,12 +1447,6 @@ dependencies = [
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "gimli"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "gimli"
version = "0.31.1"
@@ -2064,12 +2052,12 @@ dependencies = [
[[package]]
name = "libloading"
version = "0.8.6"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.53.0",
]
[[package]]
@@ -2263,15 +2251,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
]
[[package]]
name = "miniz_oxide"
version = "0.8.8"
@@ -2327,9 +2306,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.29.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags",
"cfg-if",
@@ -2483,15 +2462,6 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "object"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.36.7"
@@ -2567,7 +2537,6 @@ dependencies = [
"humansize",
"humantime",
"log",
"serde",
"serde_json",
"sysinfo",
"tabled",
@@ -3094,9 +3063,9 @@ version = "0.2.0"
dependencies = [
"bstr",
"build_helper",
"gimli 0.31.1",
"gimli",
"libc",
"object 0.36.7",
"object",
"regex",
"serde_json",
"similar",
@@ -3403,11 +3372,11 @@ name = "rustc_codegen_llvm"
version = "0.0.0"
dependencies = [
"bitflags",
"gimli 0.31.1",
"gimli",
"itertools",
"libc",
"measureme",
"object 0.36.7",
"object",
"rustc-demangle",
"rustc_abi",
"rustc_ast",
@@ -3448,7 +3417,7 @@ dependencies = [
"either",
"itertools",
"libc",
"object 0.36.7",
"object",
"pathdiff",
"regex",
"rustc_abi",
@@ -4330,6 +4299,7 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@@ -4465,7 +4435,7 @@ name = "rustc_target"
version = "0.0.0"
dependencies = [
"bitflags",
"object 0.36.7",
"object",
"rustc_abi",
"rustc_data_structures",
"rustc_fs_util",
@@ -5229,9 +5199,9 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e9c1e705f82a260173f3eec93f2ff6d7807f23ad5a8cc2e7316a891733ea7a1"
dependencies = [
"gimli 0.31.1",
"gimli",
"hashbrown",
"object 0.36.7",
"object",
"tracing",
]
+166
View File
@@ -1,3 +1,169 @@
Version 1.87.0 (2025-05-15)
==========================
<a id="1.87.0-Language"></a>
Language
--------
- [Stabilize `asm_goto` feature](https://github.com/rust-lang/rust/pull/133870)
- [Allow parsing open beginning ranges (`..EXPR`) after unary operators `!`, `-`, and `*`](https://github.com/rust-lang/rust/pull/134900).
- [Don't require method impls for methods with `Self: Sized` bounds in `impl`s for unsized types](https://github.com/rust-lang/rust/pull/135480)
- [Stabilize `feature(precise_capturing_in_traits)` allowing `use<...>` bounds on return position `impl Trait` in `trait`s](https://github.com/rust-lang/rust/pull/138128)
<a id="1.87.0-Compiler"></a>
Compiler
--------
- [x86: make SSE2 required for i686 targets and use it to pass SIMD types](https://github.com/rust-lang/rust/pull/135408)
<a id="1.87.0-Platform-Support"></a>
Platform Support
----------------
- [Remove `i586-pc-windows-msvc` target](https://github.com/rust-lang/rust/pull/137957)
Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.
[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html
<a id="1.87.0-Libraries"></a>
Libraries
---------
- [Stabilize the anonymous pipe API](https://github.com/rust-lang/rust/issues/127154)
- [Add support for unbounded left/right shift operations](https://github.com/rust-lang/rust/issues/129375)
- [Print pointer metadata in `Debug` impl of raw pointers](https://github.com/rust-lang/rust/pull/135080)
- [`Vec::with_capacity` guarantees it allocates with the amount requested, even if `Vec::capacity` returns a different number.](https://github.com/rust-lang/rust/pull/135933)
- Most `std::arch` intrinsics which don't take pointer arguments can now be called from safe code if the caller has the appropriate target features already enabled (https://github.com/rust-lang/stdarch/pull/1714, https://github.com/rust-lang/stdarch/pull/1716, https://github.com/rust-lang/stdarch/pull/1717)
- [Undeprecate `env::home_dir`](https://github.com/rust-lang/rust/pull/137327)
- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
- [Macros such as `assert_eq!` and `vec!` now support `const {...}` expressions](https://github.com/rust-lang/rust/pull/138162)
<a id="1.87.0-Stabilized-APIs"></a>
Stabilized APIs
---------------
- [`Vec::extract_if`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.extract_if)
- [`vec::ExtractIf`](https://doc.rust-lang.org/stable/std/vec/struct.ExtractIf.html)
- [`LinkedList::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.LinkedList.html#method.extract_if)
- [`linked_list::ExtractIf`](https://doc.rust-lang.org/stable/std/collections/linked_list/struct.ExtractIf.html)
- [`<[T]>::split_off`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off)
- [`<[T]>::split_off_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_mut)
- [`<[T]>::split_off_first`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first)
- [`<[T]>::split_off_first_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_first_mut)
- [`<[T]>::split_off_last`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last)
- [`<[T]>::split_off_last_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_off_last_mut)
- [`String::extend_from_within`](https://doc.rust-lang.org/stable/alloc/string/struct.String.html#method.extend_from_within)
- [`os_str::Display`](https://doc.rust-lang.org/stable/std/ffi/os_str/struct.Display.html)
- [`OsString::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.display)
- [`OsStr::display`](https://doc.rust-lang.org/stable/std/ffi/struct.OsStr.html#method.display)
- [`io::pipe`](https://doc.rust-lang.org/stable/std/io/fn.pipe.html)
- [`io::PipeReader`](https://doc.rust-lang.org/stable/std/io/struct.PipeReader.html)
- [`io::PipeWriter`](https://doc.rust-lang.org/stable/std/io/struct.PipeWriter.html)
- [`impl From<PipeReader> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeReader%3E-for-OwnedHandle)
- [`impl From<PipeWriter> for OwnedHandle`](https://doc.rust-lang.org/stable/std/os/windows/io/struct.OwnedHandle.html#impl-From%3CPipeWriter%3E-for-OwnedHandle)
- [`impl From<PipeReader> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html)
- [`impl From<PipeWriter> for Stdio`](https://doc.rust-lang.org/stable/std/process/struct.Stdio.html#impl-From%3CPipeWriter%3E-for-Stdio)
- [`impl From<PipeReader> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeReader%3E-for-OwnedFd)
- [`impl From<PipeWriter> for OwnedFd`](https://doc.rust-lang.org/stable/std/os/fd/struct.OwnedFd.html#impl-From%3CPipeWriter%3E-for-OwnedFd)
- [`Box<MaybeUninit<T>>::write`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.write)
- [`impl TryFrom<Vec<u8>> for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-TryFrom%3CVec%3Cu8%3E%3E-for-String)
- [`<*const T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned)
- [`<*const T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned)
- [`<*mut T>::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from_unsigned-1)
- [`<*mut T>::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.byte_offset_from_unsigned-1)
- [`NonNull::offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.offset_from_unsigned)
- [`NonNull::byte_offset_from_unsigned`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.byte_offset_from_unsigned)
- [`<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.cast_signed)
- [`NonZero::<uN>::cast_signed`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_signed-5).
- [`<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.cast_unsigned).
- [`NonZero::<iN>::cast_unsigned`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.cast_unsigned-5).
- [`<uN>::is_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.is_multiple_of)
- [`<uN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shl)
- [`<uN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unbounded_shr)
- [`<iN>::unbounded_shl`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shl)
- [`<iN>::unbounded_shr`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unbounded_shr)
- [`<iN>::midpoint`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.midpoint)
- [`<str>::from_utf8`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8)
- [`<str>::from_utf8_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_mut)
- [`<str>::from_utf8_unchecked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked)
- [`<str>::from_utf8_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.from_utf8_unchecked_mut)
These previously stable APIs are now stable in const contexts:
- [`core::str::from_utf8_mut`](https://doc.rust-lang.org/stable/std/str/fn.from_utf8_mut.html)
- [`<[T]>::copy_from_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.copy_from_slice)
- [`SocketAddr::set_ip`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_ip)
- [`SocketAddr::set_port`](https://doc.rust-lang.org/stable/std/net/enum.SocketAddr.html#method.set_port),
- [`SocketAddrV4::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_ip)
- [`SocketAddrV4::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV4.html#method.set_port),
- [`SocketAddrV6::set_ip`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_ip)
- [`SocketAddrV6::set_port`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_port)
- [`SocketAddrV6::set_flowinfo`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_flowinfo)
- [`SocketAddrV6::set_scope_id`](https://doc.rust-lang.org/stable/std/net/struct.SocketAddrV6.html#method.set_scope_id)
- [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit)
- [`char::is_whitespace`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_whitespace)
- [`<[[T; N]]>::as_flattened`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened)
- [`<[[T; N]]>::as_flattened_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_flattened_mut)
- [`String::into_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_bytes)
- [`String::as_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_str)
- [`String::capacity`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.capacity)
- [`String::as_bytes`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_bytes)
- [`String::len`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.len)
- [`String::is_empty`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.is_empty)
- [`String::as_mut_str`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_str)
- [`String::as_mut_vec`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.as_mut_vec)
- [`Vec::as_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_ptr)
- [`Vec::as_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_slice)
- [`Vec::capacity`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.capacity)
- [`Vec::len`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.len)
- [`Vec::is_empty`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.is_empty)
- [`Vec::as_mut_slice`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_slice)
- [`Vec::as_mut_ptr`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_ptr)
<a id="1.87.0-Cargo"></a>
Cargo
-----
- [Add terminal integration via ANSI OSC 9;4 sequences](https://github.com/rust-lang/cargo/pull/14615/)
- [chore: bump openssl to v3](https://github.com/rust-lang/cargo/pull/15232/)
- [feat(package): add --exclude-lockfile flag](https://github.com/rust-lang/cargo/pull/15234/)
<a id="1.87.0-Compatibility-Notes"></a>
Compatibility Notes
-------------------
- [Rust now raises an error for macro invocations inside the `#![crate_name]` attribute](https://github.com/rust-lang/rust/pull/127581)
- [Unstable fields are now always considered to be inhabited](https://github.com/rust-lang/rust/pull/133889)
- [Macro arguments of unary operators followed by open beginning ranges may now be matched differently](https://github.com/rust-lang/rust/pull/134900)
- [Make `Debug` impl of raw pointers print metadata if present](https://github.com/rust-lang/rust/pull/135080)
- [Warn against function pointers using unsupported ABI strings in dependencies](https://github.com/rust-lang/rust/pull/135767)
- [Associated types on `dyn` types are no longer deduplicated](https://github.com/rust-lang/rust/pull/136458)
- [Forbid attributes on `..` inside of struct patterns (`let Struct { #[attribute] .. }) =`](https://github.com/rust-lang/rust/pull/136490)
- [Make `ptr_cast_add_auto_to_object` lint into hard error](https://github.com/rust-lang/rust/pull/136764)
- Many `std::arch` intrinsics are now safe to call in some contexts, there may now be new `unused_unsafe` warnings in existing codebases.
- [Limit `width` and `precision` formatting options to 16 bits on all targets](https://github.com/rust-lang/rust/pull/136932)
- [Turn order dependent trait objects future incompat warning into a hard error](https://github.com/rust-lang/rust/pull/136968)
- [Denote `ControlFlow` as `#[must_use]`](https://github.com/rust-lang/rust/pull/137449)
- [Windows: The standard library no longer links `advapi32`, except on win7.](https://github.com/rust-lang/rust/pull/138233) Code such as C libraries that were relying on this assumption may need to explicitly link advapi32.
- [Proc macros can no longer observe expanded `cfg(true)` attributes.](https://github.com/rust-lang/rust/pull/138844)
- [Start changing the internal representation of pasted tokens](https://github.com/rust-lang/rust/pull/124141). Certain invalid declarative macros that were previously accepted in obscure circumstances are now correctly rejected by the compiler. Use of a `tt` fragment specifier can often fix these macros.
- [Don't allow flattened format_args in const.](https://github.com/rust-lang/rust/pull/139624)
<a id="1.87.0-Internal-Changes"></a>
Internal Changes
----------------
These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.
- [Update to LLVM 20](https://github.com/rust-lang/rust/pull/135763)
Version 1.86.0 (2025-04-03)
==========================
+1 -2
View File
@@ -308,7 +308,6 @@ pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
}
}
use crate::AstDeref;
pub use crate::node_id::{CRATE_NODE_ID, DUMMY_NODE_ID, NodeId};
/// Modifiers on a trait bound like `~const`, `?` and `!`.
@@ -2349,7 +2348,7 @@ pub fn peel_refs(&self) -> &Self {
pub fn is_maybe_parenthesised_infer(&self) -> bool {
match &self.kind {
TyKind::Infer => true,
TyKind::Paren(inner) => inner.ast_deref().is_maybe_parenthesised_infer(),
TyKind::Paren(inner) => inner.is_maybe_parenthesised_infer(),
_ => false,
}
}
+31 -50
View File
@@ -13,34 +13,6 @@
Ty, Variant, Visibility, WherePredicate,
};
/// A utility trait to reduce boilerplate.
/// Standard `Deref(Mut)` cannot be reused due to coherence.
pub trait AstDeref {
type Target;
fn ast_deref(&self) -> &Self::Target;
fn ast_deref_mut(&mut self) -> &mut Self::Target;
}
macro_rules! impl_not_ast_deref {
($($T:ty),+ $(,)?) => {
$(
impl !AstDeref for $T {}
)+
};
}
impl_not_ast_deref!(AssocItem, Expr, ForeignItem, Item, Stmt);
impl<T> AstDeref for P<T> {
type Target = T;
fn ast_deref(&self) -> &Self::Target {
self
}
fn ast_deref_mut(&mut self) -> &mut Self::Target {
self
}
}
/// A trait for AST nodes having an ID.
pub trait HasNodeId {
fn node_id(&self) -> NodeId;
@@ -81,12 +53,12 @@ fn node_id_mut(&mut self) -> &mut NodeId {
WherePredicate,
);
impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T {
impl<T: HasNodeId> HasNodeId for P<T> {
fn node_id(&self) -> NodeId {
self.ast_deref().node_id()
(**self).node_id()
}
fn node_id_mut(&mut self) -> &mut NodeId {
self.ast_deref_mut().node_id_mut()
(**self).node_id_mut()
}
}
@@ -138,15 +110,6 @@ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
WherePredicate
);
impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.ast_deref().tokens()
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
self.ast_deref_mut().tokens_mut()
}
}
impl<T: HasTokens> HasTokens for Option<T> {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
self.as_ref().and_then(|inner| inner.tokens())
@@ -156,6 +119,15 @@ fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
}
}
impl<T: HasTokens> HasTokens for P<T> {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
(**self).tokens()
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
(**self).tokens_mut()
}
}
impl HasTokens for StmtKind {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match self {
@@ -273,13 +245,13 @@ fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {}
);
impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T {
const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::Target::SUPPORTS_CUSTOM_INNER_ATTRS;
impl<T: HasAttrs> HasAttrs for P<T> {
const SUPPORTS_CUSTOM_INNER_ATTRS: bool = T::SUPPORTS_CUSTOM_INNER_ATTRS;
fn attrs(&self) -> &[Attribute] {
self.ast_deref().attrs()
(**self).attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.ast_deref_mut().visit_attrs(f)
(**self).visit_attrs(f);
}
}
@@ -343,13 +315,22 @@ pub fn new(wrapped: Wrapped, _tag: Tag) -> AstNodeWrapper<Wrapped, Tag> {
}
}
impl<Wrapped, Tag> AstDeref for AstNodeWrapper<Wrapped, Tag> {
type Target = Wrapped;
fn ast_deref(&self) -> &Self::Target {
&self.wrapped
impl<Wrapped: HasNodeId, Tag> HasNodeId for AstNodeWrapper<Wrapped, Tag> {
fn node_id(&self) -> NodeId {
self.wrapped.node_id()
}
fn ast_deref_mut(&mut self) -> &mut Self::Target {
&mut self.wrapped
fn node_id_mut(&mut self) -> &mut NodeId {
self.wrapped.node_id_mut()
}
}
impl<Wrapped: HasAttrs, Tag> HasAttrs for AstNodeWrapper<Wrapped, Tag> {
const SUPPORTS_CUSTOM_INNER_ATTRS: bool = Wrapped::SUPPORTS_CUSTOM_INNER_ATTRS;
fn attrs(&self) -> &[Attribute] {
self.wrapped.attrs()
}
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
self.wrapped.visit_attrs(f);
}
}
+1 -2
View File
@@ -6,7 +6,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(deny(warnings)))
@@ -46,7 +45,7 @@ pub mod util {
pub mod visit;
pub use self::ast::*;
pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens};
pub use self::ast_traits::{AstNodeWrapper, HasAttrs, HasNodeId, HasTokens};
/// Requirements for a `StableHashingContext` to be used in this crate.
/// This is a hack to allow using the `HashStable_Generic` derive macro
+1 -2
View File
@@ -32,7 +32,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
@@ -896,7 +895,7 @@ fn lower_attrs(
let ret = self.arena.alloc_from_iter(lowered_attrs);
// this is possible if an item contained syntactical attribute,
// but none of them parse succesfully or all of them were ignored
// but none of them parse successfully or all of them were ignored
// for not being built-in attributes at all. They could be remaining
// unexpanded attributes used as markers in proc-macro derives for example.
// This will have emitted some diagnostics for the misparse, but will then
-1
View File
@@ -4,7 +4,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
@@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
@@ -53,7 +53,7 @@ fn parse_unstable<'a>(
for param in list.mixed() {
let param_span = param.span();
if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
if let Some(ident) = param.meta_item().and_then(|i| i.path_without_args().word()) {
res.push(ident.name);
} else {
cx.emit_err(session_diagnostics::ExpectsFeatures {
@@ -1,5 +1,4 @@
use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, sym};
use super::SingleAttributeParser;
@@ -13,16 +12,13 @@
fn get(
cx: &AcceptContext<'_>,
ident: Ident,
name: Symbol,
param_span: Span,
arg: &ArgParser<'_>,
item: &Option<Symbol>,
) -> Option<Symbol> {
if item.is_some() {
cx.emit_err(session_diagnostics::MultipleItem {
span: param_span,
item: ident.to_string(),
});
cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() });
return None;
}
if let Some(v) = arg.name_value() {
@@ -83,16 +79,16 @@ fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind
return None;
};
let (ident, arg) = param.word_or_empty();
let ident_name = param.path_without_args().word_sym();
match ident.name {
sym::since => {
since = Some(get(cx, ident, param_span, arg, &since)?);
match ident_name {
Some(name @ sym::since) => {
since = Some(get(cx, name, param_span, param.args(), &since)?);
}
sym::note => {
note = Some(get(cx, ident, param_span, arg, &note)?);
Some(name @ sym::note) => {
note = Some(get(cx, name, param_span, param.args(), &note)?);
}
sym::suggestion => {
Some(name @ sym::suggestion) => {
if !features.deprecated_suggestion() {
cx.emit_err(session_diagnostics::DeprecatedItemSuggestion {
span: param_span,
@@ -101,12 +97,12 @@ fn convert(cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind
});
}
suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?);
suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?);
}
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
item: ident.to_string(),
item: param.path_without_args().to_string(),
expected: if features.deprecated_suggestion() {
&["since", "note", "suggestion"]
} else {
@@ -96,58 +96,75 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option<Repr
// FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
// structure.
let (ident, args) = param.word_or_empty();
let (name, ident_span) = if let Some(ident) = param.path_without_args().word() {
(Some(ident.name), ident.span)
} else {
(None, rustc_span::DUMMY_SP)
};
match (ident.name, args) {
(sym::align, ArgParser::NoArgs) => {
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span });
let args = param.args();
match (name, args) {
(Some(sym::align), ArgParser::NoArgs) => {
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
None
}
(sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align),
(Some(sym::align), ArgParser::List(l)) => {
parse_repr_align(cx, l, param.span(), AlignKind::Align)
}
(sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
(sym::packed, ArgParser::List(l)) => {
(Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
(Some(sym::packed), ArgParser::List(l)) => {
parse_repr_align(cx, l, param.span(), AlignKind::Packed)
}
(sym::align | sym::packed, ArgParser::NameValue(l)) => {
(Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => {
cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
span: param.span(),
// FIXME(jdonszelmann) can just be a string in the diag type
repr_arg: &ident.to_string(),
repr_arg: name,
cause: IncorrectReprFormatGenericCause::from_lit_kind(
param.span(),
&l.value_as_lit().kind,
ident.name.as_str(),
name,
),
});
None
}
(sym::Rust, ArgParser::NoArgs) => Some(ReprRust),
(sym::C, ArgParser::NoArgs) => Some(ReprC),
(sym::simd, ArgParser::NoArgs) => Some(ReprSimd),
(sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent),
(i @ int_pat!(), ArgParser::NoArgs) => {
(Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
(Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
(Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
(Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
(Some(name @ int_pat!()), ArgParser::NoArgs) => {
// int_pat!() should make sure it always parses
Some(ReprInt(int_type_of_word(i).unwrap()))
Some(ReprInt(int_type_of_word(name).unwrap()))
}
(
sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(),
Some(
name @ sym::Rust
| name @ sym::C
| name @ sym::simd
| name @ sym::transparent
| name @ int_pat!(),
),
ArgParser::NameValue(_),
) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoValue {
span: param.span(),
name: ident.to_string(),
});
cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name });
None
}
(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoParen {
span: param.span(),
name: ident.to_string(),
});
(
Some(
name @ sym::Rust
| name @ sym::C
| name @ sym::simd
| name @ sym::transparent
| name @ int_pat!(),
),
ArgParser::List(_),
) => {
cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name });
None
}
@@ -242,9 +242,9 @@ pub(crate) fn parse_stability(
return None;
};
match param.word_or_empty_without_args().name {
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
sym::since => insert_value_into_option_or_error(cx, &param, &mut since)?,
match param.path_without_args().word_sym() {
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
Some(sym::since) => insert_value_into_option_or_error(cx, &param, &mut since)?,
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param_span,
@@ -310,11 +310,10 @@ pub(crate) fn parse_unstability(
return None;
};
let (word, args) = param.word_or_empty();
match word.name {
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
sym::reason => insert_value_into_option_or_error(cx, &param, &mut reason)?,
sym::issue => {
match param.path_without_args().word_sym() {
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
Some(sym::reason) => insert_value_into_option_or_error(cx, &param, &mut reason)?,
Some(sym::issue) => {
insert_value_into_option_or_error(cx, &param, &mut issue)?;
// These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item
@@ -328,7 +327,7 @@ pub(crate) fn parse_unstability(
session_diagnostics::InvalidIssueString {
span: param.span(),
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
args.name_value().unwrap().value_span,
param.args().name_value().unwrap().value_span,
err.kind(),
),
},
@@ -338,13 +337,15 @@ pub(crate) fn parse_unstability(
},
};
}
sym::soft => {
if !args.no_args() {
Some(sym::soft) => {
if !param.args().no_args() {
cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
}
is_soft = true;
}
sym::implied_by => insert_value_into_option_or_error(cx, &param, &mut implied_by)?,
Some(sym::implied_by) => {
insert_value_into_option_or_error(cx, &param, &mut implied_by)?
}
_ => {
cx.emit_err(session_diagnostics::UnknownMetaItem {
span: param.span(),
-1
View File
@@ -77,7 +77,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![recursion_limit = "256"]
+2 -13
View File
@@ -78,8 +78,8 @@ pub fn word(&self) -> Option<Ident> {
(self.len() == 1).then(|| **self.segments().next().as_ref().unwrap())
}
pub fn word_or_empty(&self) -> Ident {
self.word().unwrap_or_else(Ident::empty)
pub fn word_sym(&self) -> Option<Symbol> {
self.word().map(|ident| ident.name)
}
/// Asserts that this MetaItem is some specific word.
@@ -284,11 +284,6 @@ pub fn word_without_args(&self) -> Option<Ident> {
Some(self.word()?.0)
}
/// Like [`word`](Self::word), but returns an empty symbol instead of None
pub fn word_or_empty_without_args(&self) -> Ident {
self.word_or_empty().0
}
/// Asserts that this MetaItem starts with a word, or single segment path.
///
/// Some examples:
@@ -300,12 +295,6 @@ pub fn word(&self) -> Option<(Ident, &ArgParser<'a>)> {
Some((path.word()?, args))
}
/// Like [`word`](Self::word), but returns an empty symbol instead of None
pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) {
let (path, args) = self.deconstruct();
(path.word().unwrap_or(Ident::empty()), args)
}
/// Asserts that this MetaItem starts with some specific word.
///
/// See [`word`](Self::word) for examples of what a word is.
@@ -204,7 +204,7 @@ pub(crate) struct InvalidReprHintNoParen {
#[primary_span]
pub span: Span,
pub name: String,
pub name: Symbol,
}
#[derive(Diagnostic)]
@@ -213,7 +213,7 @@ pub(crate) struct InvalidReprHintNoValue {
#[primary_span]
pub span: Span,
pub name: String,
pub name: Symbol,
}
/// Error code: E0565
@@ -295,21 +295,21 @@ pub(crate) struct IncorrectReprFormatExpectInteger {
#[derive(Diagnostic)]
#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
pub(crate) struct IncorrectReprFormatGeneric<'a> {
pub(crate) struct IncorrectReprFormatGeneric {
#[primary_span]
pub span: Span,
pub repr_arg: &'a str,
pub repr_arg: Symbol,
#[subdiagnostic]
pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
pub cause: Option<IncorrectReprFormatGenericCause>,
}
#[derive(Subdiagnostic)]
pub(crate) enum IncorrectReprFormatGenericCause<'a> {
pub(crate) enum IncorrectReprFormatGenericCause {
#[suggestion(
attr_parsing_suggestion,
code = "{name}({int})",
code = "{name}({value})",
applicability = "machine-applicable"
)]
Int {
@@ -317,15 +317,15 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
span: Span,
#[skip_arg]
name: &'a str,
name: Symbol,
#[skip_arg]
int: u128,
value: u128,
},
#[suggestion(
attr_parsing_suggestion,
code = "{name}({symbol})",
code = "{name}({value})",
applicability = "machine-applicable"
)]
Symbol {
@@ -333,20 +333,20 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
span: Span,
#[skip_arg]
name: &'a str,
name: Symbol,
#[skip_arg]
symbol: Symbol,
value: Symbol,
},
}
impl<'a> IncorrectReprFormatGenericCause<'a> {
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
match kind {
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
Some(Self::Int { span, name, int: int.get() })
impl IncorrectReprFormatGenericCause {
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
match *kind {
ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
Some(Self::Int { span, name, value: value.get() })
}
ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
_ => None,
}
}
-1
View File
@@ -2,7 +2,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
@@ -266,10 +266,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t
where
OP: FnMut(ty::Region<'tcx>),
{
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
t.super_visit_with(self);
}
fn visit_region(&mut self, r: ty::Region<'tcx>) {
match r.kind() {
// ignore bound regions, keep visiting
+3 -3
View File
@@ -8,7 +8,7 @@
use rustc_ast::token::{self, LitKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability};
use rustc_ast::{ExprKind, GenericArg, Mutability};
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::{Ident, Span, Symbol, kw, sym};
use thin_vec::thin_vec;
@@ -148,13 +148,13 @@ pub(crate) fn expand_env<'cx>(
cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar {
span,
var: *symbol,
var_expr: var_expr.ast_deref(),
var_expr: &var_expr,
})
} else {
cx.dcx().emit_err(errors::EnvNotDefined::CustomEnvVar {
span,
var: *symbol,
var_expr: var_expr.ast_deref(),
var_expr: &var_expr,
})
}
}
-1
View File
@@ -5,7 +5,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@@ -1109,6 +1109,43 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret.write_cvalue(fx, old);
}
sym::minimumf32 => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let a = a.load_scalar(fx);
let b = b.load_scalar(fx);
let val = fx.bcx.ins().fmin(a, b);
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
ret.write_cvalue(fx, val);
}
sym::minimumf64 => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let a = a.load_scalar(fx);
let b = b.load_scalar(fx);
let val = fx.bcx.ins().fmin(a, b);
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
ret.write_cvalue(fx, val);
}
sym::maximumf32 => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let a = a.load_scalar(fx);
let b = b.load_scalar(fx);
let val = fx.bcx.ins().fmax(a, b);
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
ret.write_cvalue(fx, val);
}
sym::maximumf64 => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let a = a.load_scalar(fx);
let b = b.load_scalar(fx);
let val = fx.bcx.ins().fmax(a, b);
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
ret.write_cvalue(fx, val);
}
sym::minnumf32 => {
intrinsic_args!(fx, args => (a, b); intrinsic);
let a = a.load_scalar(fx);
@@ -2454,7 +2454,6 @@ fn to_gcc(self) -> i32 {
use MemOrdering::*;
let ordering = match self {
AtomicOrdering::Unordered => __ATOMIC_RELAXED,
AtomicOrdering::Relaxed => __ATOMIC_RELAXED, // TODO(antoyo): check if that's the same.
AtomicOrdering::Acquire => __ATOMIC_ACQUIRE,
AtomicOrdering::Release => __ATOMIC_RELEASE,
@@ -74,8 +74,44 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
sym::fabsf64 => "fabs",
sym::minnumf32 => "fminf",
sym::minnumf64 => "fmin",
sym::minimumf32 => "fminimumf",
sym::minimumf64 => "fminimum",
sym::minimumf128 => {
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fminimumf128.html
let f128_type = cx.type_f128();
return Some(cx.context.new_function(
None,
FunctionType::Extern,
f128_type,
&[
cx.context.new_parameter(None, f128_type, "a"),
cx.context.new_parameter(None, f128_type, "b"),
],
"fminimumf128",
false,
));
}
sym::maxnumf32 => "fmaxf",
sym::maxnumf64 => "fmax",
sym::maximumf32 => "fmaximumf",
sym::maximumf64 => "fmaximum",
sym::maximumf128 => {
// GCC doesn't have the intrinsic we want so we use the compiler-builtins one
// https://docs.rs/compiler_builtins/latest/compiler_builtins/math/full_availability/fn.fmaximumf128.html
let f128_type = cx.type_f128();
return Some(cx.context.new_function(
None,
FunctionType::Extern,
f128_type,
&[
cx.context.new_parameter(None, f128_type, "a"),
cx.context.new_parameter(None, f128_type, "b"),
],
"fmaximumf128",
false,
));
}
sym::copysignf32 => "copysignf",
sym::copysignf64 => "copysign",
sym::copysignf128 => "copysignl",
+60 -66
View File
@@ -14,7 +14,7 @@
use tracing::debug;
use crate::builder::Builder;
use crate::common::{AsCCharPtr, Funclet};
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
@@ -435,13 +435,7 @@ fn codegen_global_asm(
template_str.push_str("\n.att_syntax\n");
}
unsafe {
llvm::LLVMAppendModuleInlineAsm(
self.llmod,
template_str.as_c_char_ptr(),
template_str.len(),
);
}
llvm::append_module_inline_asm(self.llmod, template_str.as_bytes());
}
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
@@ -482,67 +476,67 @@ pub(crate) fn inline_asm_call<'ll>(
debug!("Asm Output Type: {:?}", output);
let fty = bx.cx.type_func(&argtys, output);
// Ask LLVM to verify that the constraints are well-formed.
let constraints_ok =
unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_c_char_ptr(), cons.len()) };
let constraints_ok = unsafe { llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr(), cons.len()) };
debug!("constraint verification result: {:?}", constraints_ok);
if constraints_ok {
let v = unsafe {
llvm::LLVMRustInlineAsm(
fty,
asm.as_c_char_ptr(),
asm.len(),
cons.as_c_char_ptr(),
cons.len(),
volatile,
alignstack,
dia,
can_throw,
)
};
let call = if !labels.is_empty() {
assert!(catch_funclet.is_none());
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
} else if let Some((catch, funclet)) = catch_funclet {
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
} else {
bx.call(fty, None, None, v, inputs, None, None)
};
// Store mark in a metadata node so we can map LLVM errors
// back to source locations. See #17552.
let key = "srcloc";
let kind = bx.get_md_kind_id(key);
// `srcloc` contains one 64-bit integer for each line of assembly code,
// where the lower 32 bits hold the lo byte position and the upper 32 bits
// hold the hi byte position.
let mut srcloc = vec![];
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
// LLVM inserts an extra line to add the ".intel_syntax", so add
// a dummy srcloc entry for it.
//
// Don't do this if we only have 1 line span since that may be
// due to the asm template string coming from a macro. LLVM will
// default to the first srcloc for lines that don't have an
// associated srcloc.
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
}
srcloc.extend(line_spans.iter().map(|span| {
llvm::LLVMValueAsMetadata(
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
)
}));
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
let md = bx.get_metadata_value(md);
llvm::LLVMSetMetadata(call, kind, md);
Some(call)
} else {
// LLVM has detected an issue with our constraints, bail out
None
if !constraints_ok {
// LLVM has detected an issue with our constraints, so bail out.
return None;
}
let v = unsafe {
llvm::LLVMGetInlineAsm(
fty,
asm.as_ptr(),
asm.len(),
cons.as_ptr(),
cons.len(),
volatile,
alignstack,
dia,
can_throw,
)
};
let call = if !labels.is_empty() {
assert!(catch_funclet.is_none());
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
} else if let Some((catch, funclet)) = catch_funclet {
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
} else {
bx.call(fty, None, None, v, inputs, None, None)
};
// Store mark in a metadata node so we can map LLVM errors
// back to source locations. See #17552.
let key = "srcloc";
let kind = bx.get_md_kind_id(key);
// `srcloc` contains one 64-bit integer for each line of assembly code,
// where the lower 32 bits hold the lo byte position and the upper 32 bits
// hold the hi byte position.
let mut srcloc = vec![];
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
// LLVM inserts an extra line to add the ".intel_syntax", so add
// a dummy srcloc entry for it.
//
// Don't do this if we only have 1 line span since that may be
// due to the asm template string coming from a macro. LLVM will
// default to the first srcloc for lines that don't have an
// associated srcloc.
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
}
srcloc.extend(line_spans.iter().map(|span| {
llvm::LLVMValueAsMetadata(
bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)),
)
}));
let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) };
let md = bx.get_metadata_value(md);
llvm::LLVMSetMetadata(call, kind, md);
Some(call)
}
/// If the register is an xmm/ymm/zmm register then return its index.
@@ -1148,9 +1148,9 @@ unsafe fn embed_bitcode(
// We need custom section flags, so emit module-level inline assembly.
let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
llvm::append_module_inline_asm(llmod, &asm);
let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_c_char_ptr(), asm.len());
llvm::append_module_inline_asm(llmod, &asm);
}
}
}
+5 -5
View File
@@ -361,7 +361,7 @@ fn invoke(
// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) {
bundles.push(kcfi_bundle);
}
@@ -1416,7 +1416,7 @@ fn call(
// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) {
bundles.push(kcfi_bundle);
}
@@ -1749,7 +1749,7 @@ pub(crate) fn callbr(
// Emit KCFI operand bundle
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) {
bundles.push(kcfi_bundle);
}
@@ -1836,7 +1836,7 @@ fn kcfi_operand_bundle(
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
instance: Option<Instance<'tcx>>,
llfn: &'ll Value,
) -> Option<llvm::OperandBundleOwned<'ll>> {
) -> Option<llvm::OperandBundleBox<'ll>> {
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
let kcfi_bundle = if self.tcx.sess.is_sanitizer_kcfi_enabled()
&& let Some(fn_abi) = fn_abi
@@ -1862,7 +1862,7 @@ fn kcfi_operand_bundle(
kcfi::typeid_for_fnabi(self.tcx, fn_abi, options)
};
Some(llvm::OperandBundleOwned::new("kcfi", &[self.const_u32(kcfi_typeid)]))
Some(llvm::OperandBundleBox::new("kcfi", &[self.const_u32(kcfi_typeid)]))
} else {
None
};
+3 -3
View File
@@ -67,12 +67,12 @@
/// the `OperandBundleDef` value created for MSVC landing pads.
pub(crate) struct Funclet<'ll> {
cleanuppad: &'ll Value,
operand: llvm::OperandBundleOwned<'ll>,
operand: llvm::OperandBundleBox<'ll>,
}
impl<'ll> Funclet<'ll> {
pub(crate) fn new(cleanuppad: &'ll Value) -> Self {
Funclet { cleanuppad, operand: llvm::OperandBundleOwned::new("funclet", &[cleanuppad]) }
Funclet { cleanuppad, operand: llvm::OperandBundleBox::new("funclet", &[cleanuppad]) }
}
pub(crate) fn cleanuppad(&self) -> &'ll Value {
@@ -80,7 +80,7 @@ pub(crate) fn cleanuppad(&self) -> &'ll Value {
}
pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
self.operand.raw()
self.operand.as_ref()
}
}
+6 -1
View File
@@ -364,7 +364,12 @@ fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs
&& !self.tcx.is_foreign_item(def_id)
// If the symbol is a foreign item, then don't automatically apply DLLImport, as
// we'll rely on the #[link] attribute instead. BUT, if this is an internal symbol
// then it may be generated by the compiler in some crate, so we do need to apply
// DLLImport when linking with the MSVC linker.
&& (!self.tcx.is_foreign_item(def_id)
|| (self.sess().target.is_like_msvc && fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)))
// Local definitions can never be imported, so we must not apply
// the DLLImport annotation.
&& !dso_local
@@ -1009,11 +1009,27 @@ macro_rules! mk_struct {
ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
ifn!("llvm.minnum.f128", fn(t_f128, t_f128) -> t_f128);
ifn!("llvm.minimum.f16", fn(t_f16, t_f16) -> t_f16);
ifn!("llvm.minimum.f32", fn(t_f32, t_f32) -> t_f32);
ifn!("llvm.minimum.f64", fn(t_f64, t_f64) -> t_f64);
// There are issues on x86_64 and aarch64 with the f128 variant.
// - https://github.com/llvm/llvm-project/issues/139380
// - https://github.com/llvm/llvm-project/issues/139381
// ifn!("llvm.minimum.f128", fn(t_f128, t_f128) -> t_f128);
ifn!("llvm.maxnum.f16", fn(t_f16, t_f16) -> t_f16);
ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32);
ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
ifn!("llvm.maxnum.f128", fn(t_f128, t_f128) -> t_f128);
ifn!("llvm.maximum.f16", fn(t_f16, t_f16) -> t_f16);
ifn!("llvm.maximum.f32", fn(t_f32, t_f32) -> t_f32);
ifn!("llvm.maximum.f64", fn(t_f64, t_f64) -> t_f64);
// There are issues on x86_64 and aarch64 with the f128 variant.
// - https://github.com/llvm/llvm-project/issues/139380
// - https://github.com/llvm/llvm-project/issues/139381
// ifn!("llvm.maximum.f128", fn(t_f128, t_f128) -> t_f128);
ifn!("llvm.floor.f16", fn(t_f16) -> t_f16);
ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
@@ -103,11 +103,23 @@ fn get_simple_intrinsic<'ll>(
sym::minnumf64 => "llvm.minnum.f64",
sym::minnumf128 => "llvm.minnum.f128",
sym::minimumf16 => "llvm.minimum.f16",
sym::minimumf32 => "llvm.minimum.f32",
sym::minimumf64 => "llvm.minimum.f64",
// There are issues on x86_64 and aarch64 with the f128 variant,
// let's instead use the instrinsic fallback body.
// sym::minimumf128 => "llvm.minimum.f128",
sym::maxnumf16 => "llvm.maxnum.f16",
sym::maxnumf32 => "llvm.maxnum.f32",
sym::maxnumf64 => "llvm.maxnum.f64",
sym::maxnumf128 => "llvm.maxnum.f128",
sym::maximumf16 => "llvm.maximum.f16",
sym::maximumf32 => "llvm.maximum.f32",
sym::maximumf64 => "llvm.maximum.f64",
// There are issues on x86_64 and aarch64 with the f128 variant,
// let's instead use the instrinsic fallback body.
// sym::maximumf128 => "llvm.maximum.f128",
sym::copysignf16 => "llvm.copysign.f16",
sym::copysignf32 => "llvm.copysign.f32",
sym::copysignf64 => "llvm.copysign.f64",
-1
View File
@@ -6,7 +6,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
+24 -19
View File
@@ -1,7 +1,7 @@
//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper
//! functions around the unstable LLVM C++ API (`LLVMRust*`).
//!
//! ## Passing pointer/length strings as `*const c_uchar`
//! ## Passing pointer/length strings as `*const c_uchar` (PTR_LEN_STR)
//!
//! Normally it's a good idea for Rust-side bindings to match the corresponding
//! C-side function declarations as closely as possible. But when passing `&str`
@@ -415,6 +415,7 @@ pub(crate) fn from_generic(op: rustc_codegen_ssa::common::AtomicRmwBinOp) -> Sel
pub(crate) enum AtomicOrdering {
#[allow(dead_code)]
NotAtomic = 0,
#[allow(dead_code)]
Unordered = 1,
Monotonic = 2,
// Consume = 3, // Not specified yet.
@@ -428,7 +429,6 @@ impl AtomicOrdering {
pub(crate) fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self {
use rustc_codegen_ssa::common::AtomicOrdering as Common;
match ao {
Common::Unordered => Self::Unordered,
Common::Relaxed => Self::Monotonic,
Common::Acquire => Self::Acquire,
Common::Release => Self::Release,
@@ -471,7 +471,7 @@ pub(crate) enum MetadataType {
MD_kcfi_type = 36,
}
/// LLVMRustAsmDialect
/// Must match the layout of `LLVMInlineAsmDialect`.
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub(crate) enum AsmDialect {
@@ -1014,8 +1014,25 @@ pub(crate) fn LLVMModuleCreateWithNameInContext(
pub(crate) fn LLVMGetDataLayoutStr(M: &Module) -> *const c_char;
pub(crate) fn LLVMSetDataLayout(M: &Module, Triple: *const c_char);
/// See Module::setModuleInlineAsm.
pub(crate) fn LLVMAppendModuleInlineAsm(M: &Module, Asm: *const c_char, Len: size_t);
/// Append inline assembly to a module. See `Module::appendModuleInlineAsm`.
pub(crate) fn LLVMAppendModuleInlineAsm(
M: &Module,
Asm: *const c_uchar, // See "PTR_LEN_STR".
Len: size_t,
);
/// Create the specified uniqued inline asm string. See `InlineAsm::get()`.
pub(crate) fn LLVMGetInlineAsm<'ll>(
Ty: &'ll Type,
AsmString: *const c_uchar, // See "PTR_LEN_STR".
AsmStringSize: size_t,
Constraints: *const c_uchar, // See "PTR_LEN_STR".
ConstraintsSize: size_t,
HasSideEffects: llvm::Bool,
IsAlignStack: llvm::Bool,
Dialect: AsmDialect,
CanThrow: llvm::Bool,
) -> &'ll Value;
// Operations on integer types
pub(crate) fn LLVMInt1TypeInContext(C: &Context) -> &Type;
@@ -1766,7 +1783,7 @@ pub(crate) fn LLVMBuildCallBr<'a>(
pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>(
Builder: &DIBuilder<'ll>,
ParentScope: Option<&'ll Metadata>,
Name: *const c_uchar,
Name: *const c_uchar, // See "PTR_LEN_STR".
NameLen: size_t,
ExportSymbols: llvm::Bool,
) -> &'ll Metadata;
@@ -1994,21 +2011,9 @@ pub(crate) fn LLVMRustBuildAtomicStore<'a>(
/// Prints the statistics collected by `-Zprint-codegen-stats`.
pub(crate) fn LLVMRustPrintStatistics(OutStr: &RustString);
/// Prepares inline assembly.
pub(crate) fn LLVMRustInlineAsm(
Ty: &Type,
AsmString: *const c_char,
AsmStringLen: size_t,
Constraints: *const c_char,
ConstraintsLen: size_t,
SideEffects: Bool,
AlignStack: Bool,
Dialect: AsmDialect,
CanThrow: Bool,
) -> &Value;
pub(crate) fn LLVMRustInlineAsmVerify(
Ty: &Type,
Constraints: *const c_char,
Constraints: *const c_uchar, // See "PTR_LEN_STR".
ConstraintsLen: size_t,
) -> bool;
+18 -9
View File
@@ -363,12 +363,13 @@ pub(crate) fn last_error() -> Option<String> {
}
}
/// Owns an [`OperandBundle`], and will dispose of it when dropped.
pub(crate) struct OperandBundleOwned<'a> {
/// Owning pointer to an [`OperandBundle`] that will dispose of the bundle
/// when dropped.
pub(crate) struct OperandBundleBox<'a> {
raw: ptr::NonNull<OperandBundle<'a>>,
}
impl<'a> OperandBundleOwned<'a> {
impl<'a> OperandBundleBox<'a> {
pub(crate) fn new(name: &str, vals: &[&'a Value]) -> Self {
let raw = unsafe {
LLVMCreateOperandBundle(
@@ -378,21 +379,21 @@ pub(crate) fn new(name: &str, vals: &[&'a Value]) -> Self {
vals.len() as c_uint,
)
};
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
Self { raw: ptr::NonNull::new(raw).unwrap() }
}
/// Returns inner `OperandBundle` type.
/// Dereferences to the underlying `&OperandBundle`.
///
/// This could be a `Deref` implementation, but `OperandBundle` contains an extern type and
/// `Deref::Target: ?Sized`.
pub(crate) fn raw(&self) -> &OperandBundle<'a> {
/// This can't be a `Deref` implementation because `OperandBundle` transitively
/// contains an extern type, which is incompatible with `Deref::Target: ?Sized`.
pub(crate) fn as_ref(&self) -> &OperandBundle<'a> {
// SAFETY: The returned reference is opaque and can only used for FFI.
// It is valid for as long as `&self` is.
unsafe { self.raw.as_ref() }
}
}
impl Drop for OperandBundleOwned<'_> {
impl Drop for OperandBundleBox<'_> {
fn drop(&mut self) {
unsafe {
LLVMDisposeOperandBundle(self.raw);
@@ -440,3 +441,11 @@ pub(crate) fn set_dso_local<'ll>(v: &'ll Value) {
LLVMRustSetDSOLocal(v, true);
}
}
/// Safe wrapper for `LLVMAppendModuleInlineAsm`, which delegates to
/// `Module::appendModuleInlineAsm`.
pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) {
unsafe {
LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len());
}
}
+90 -30
View File
@@ -337,7 +337,12 @@ fn add_object(&mut self, path: &Path) {
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
fn no_crt_objects(&mut self);
fn no_default_libraries(&mut self);
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
fn export_symbols(
&mut self,
tmpdir: &Path,
crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
);
fn subsystem(&mut self, subsystem: &str);
fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {}
@@ -770,7 +775,12 @@ fn no_default_libraries(&mut self) {
}
}
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
tmpdir: &Path,
crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
// Symbol visibility in object files typically takes care of this.
if crate_type == CrateType::Executable {
let should_export_executable_symbols =
@@ -799,7 +809,7 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// Write a plain, newline-separated list of symbols
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
for sym in symbols {
for (sym, _) in symbols {
debug!(" _{sym}");
writeln!(f, "_{sym}")?;
}
@@ -814,11 +824,12 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// .def file similar to MSVC one but without LIBRARY section
// because LD doesn't like when it's empty
writeln!(f, "EXPORTS")?;
for symbol in symbols {
for (symbol, kind) in symbols {
let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
debug!(" _{symbol}");
// Quote the name in case it's reserved by linker in some way
// (this accounts for names with dots in particular).
writeln!(f, " \"{symbol}\"")?;
writeln!(f, " \"{symbol}\"{kind_marker}")?;
}
};
if let Err(error) = res {
@@ -831,7 +842,7 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
writeln!(f, "{{")?;
if !symbols.is_empty() {
writeln!(f, " global:")?;
for sym in symbols {
for (sym, _) in symbols {
debug!(" {sym};");
writeln!(f, " {sym};")?;
}
@@ -1098,7 +1109,12 @@ fn debuginfo(&mut self, _strip: Strip, natvis_debugger_visualizers: &[PathBuf])
// crates. Upstream rlibs may be linked statically to this dynamic library,
// in which case they may continue to transitively be used and hence need
// their symbols exported.
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
tmpdir: &Path,
crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
// Symbol visibility takes care of this typically
if crate_type == CrateType::Executable {
let should_export_executable_symbols =
@@ -1116,9 +1132,10 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[St
// straight to exports.
writeln!(f, "LIBRARY")?;
writeln!(f, "EXPORTS")?;
for symbol in symbols {
for (symbol, kind) in symbols {
let kind_marker = if *kind == SymbolExportKind::Data { " DATA" } else { "" };
debug!(" _{symbol}");
writeln!(f, " {symbol}")?;
writeln!(f, " {symbol}{kind_marker}")?;
}
};
if let Err(error) = res {
@@ -1259,14 +1276,19 @@ fn no_default_libraries(&mut self) {
self.cc_arg("-nodefaultlibs");
}
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
_tmpdir: &Path,
_crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
debug!("EXPORTED SYMBOLS:");
self.cc_arg("-s");
let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
let encoded = serde_json::to_string(
&symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
&symbols.iter().map(|(sym, _)| "_".to_owned() + sym).collect::<Vec<_>>(),
)
.unwrap();
debug!("{encoded}");
@@ -1428,8 +1450,13 @@ fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
for sym in symbols {
fn export_symbols(
&mut self,
_tmpdir: &Path,
_crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
for (sym, _) in symbols {
self.link_args(&["--export", sym]);
}
@@ -1563,7 +1590,7 @@ fn no_default_libraries(&mut self) {
self.cc_arg("-nostdlib");
}
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[(String, SymbolExportKind)]) {
// ToDo, not implemented, copy from GCC
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
}
@@ -1720,12 +1747,17 @@ fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
tmpdir: &Path,
_crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
let path = tmpdir.join("list.exp");
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
// FIXME: use llvm-nm to generate export list.
for symbol in symbols {
for (symbol, _) in symbols {
debug!(" _{symbol}");
writeln!(f, " {symbol}")?;
}
@@ -1769,9 +1801,12 @@ fn for_each_exported_symbols_include_dep<'tcx>(
}
}
pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
pub(crate) fn exported_symbols(
tcx: TyCtxt<'_>,
crate_type: CrateType,
) -> Vec<(String, SymbolExportKind)> {
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
return exports.iter().map(ToString::to_string).collect();
return exports.iter().map(|name| (name.to_string(), SymbolExportKind::Text)).collect();
}
if let CrateType::ProcMacro = crate_type {
@@ -1781,7 +1816,10 @@ pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<St
}
}
fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
fn exported_symbols_for_non_proc_macro(
tcx: TyCtxt<'_>,
crate_type: CrateType,
) -> Vec<(String, SymbolExportKind)> {
let mut symbols = Vec::new();
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
@@ -1789,17 +1827,18 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
// from any cdylib. The latter doesn't work anyway as we use hidden visibility for
// compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) {
symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
tcx, symbol, cnum,
symbols.push((
symbol_export::exporting_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
info.kind,
));
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, cnum);
symbol_export::extend_exported_symbols(&mut symbols, tcx, symbol, info, cnum);
}
});
symbols
}
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<(String, SymbolExportKind)> {
// `exported_symbols` will be empty when !should_codegen.
if !tcx.sess.opts.output_types.should_codegen() {
return Vec::new();
@@ -1809,7 +1848,10 @@ fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec<String> {
let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id);
let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx);
vec![proc_macro_decls_name, metadata_symbol_name]
vec![
(proc_macro_decls_name, SymbolExportKind::Text),
(metadata_symbol_name, SymbolExportKind::Text),
]
}
pub(crate) fn linked_symbols(
@@ -1831,7 +1873,9 @@ pub(crate) fn linked_symbols(
|| info.used
{
symbols.push((
symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum),
symbol_export::linking_symbol_name_for_instance_in_crate(
tcx, symbol, info.kind, cnum,
),
info.kind,
));
}
@@ -1906,7 +1950,13 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
fn export_symbols(
&mut self,
_tmpdir: &Path,
_crate_type: CrateType,
_symbols: &[(String, SymbolExportKind)],
) {
}
fn subsystem(&mut self, _subsystem: &str) {}
@@ -1975,10 +2025,15 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
_tmpdir: &Path,
_crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
match _crate_type {
CrateType::Cdylib => {
for sym in symbols {
for (sym, _) in symbols {
self.link_args(&["--export-symbol", sym]);
}
}
@@ -2052,11 +2107,16 @@ fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
fn export_symbols(
&mut self,
tmpdir: &Path,
_crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
) {
let path = tmpdir.join("symbols");
let res: io::Result<()> = try {
let mut f = File::create_buffered(&path)?;
for sym in symbols {
for (sym, _) in symbols {
writeln!(f, "{sym}")?;
}
};
@@ -692,6 +692,7 @@ fn calling_convention_for_symbol<'tcx>(
pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
export_kind: SymbolExportKind,
instantiating_crate: CrateNum,
) -> String {
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
@@ -712,8 +713,9 @@ pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
let prefix = match &target.arch[..] {
"x86" => Some('_'),
"x86_64" => None,
"arm64ec" => Some('#'),
// Only x86/64 use symbol decorations.
// Only functions are decorated for arm64ec.
"arm64ec" if export_kind == SymbolExportKind::Text => Some('#'),
// Only x86/64 and arm64ec use symbol decorations.
_ => return undecorated,
};
@@ -753,9 +755,10 @@ pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
/// Add it to the symbols list for all kernel functions, so that it is exported in the linked
/// object.
pub(crate) fn extend_exported_symbols<'tcx>(
symbols: &mut Vec<String>,
symbols: &mut Vec<(String, SymbolExportKind)>,
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
info: SymbolExportInfo,
instantiating_crate: CrateNum,
) {
let (conv, _) = calling_convention_for_symbol(tcx, symbol);
@@ -767,7 +770,7 @@ pub(crate) fn extend_exported_symbols<'tcx>(
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
// Add the symbol for the kernel descriptor (with .kd suffix)
symbols.push(format!("{undecorated}.kd"));
symbols.push((format!("{undecorated}.kd"), info.kind));
}
fn maybe_emutls_symbol_name<'tcx>(
+32 -15
View File
@@ -12,9 +12,9 @@
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
use rustc_data_structures::unord::UnordMap;
use rustc_hir::ItemId;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ItemId, Target};
use rustc_metadata::EncodedMetadata;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
@@ -1038,21 +1038,35 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
// by the compiler, but that's ok because all this stuff is unstable anyway.
let target = &tcx.sess.target;
if !are_upstream_rust_objects_already_included(tcx.sess) {
let missing_weak_lang_items: FxIndexSet<Symbol> = info
let add_prefix = match (target.is_like_windows, target.arch.as_ref()) {
(true, "x86") => |name: String, _: SymbolExportKind| format!("_{name}"),
(true, "arm64ec") => {
// Only functions are decorated for arm64ec.
|name: String, export_kind: SymbolExportKind| match export_kind {
SymbolExportKind::Text => format!("#{name}"),
_ => name,
}
}
_ => |name: String, _: SymbolExportKind| name,
};
let missing_weak_lang_items: FxIndexSet<(Symbol, SymbolExportKind)> = info
.used_crates
.iter()
.flat_map(|&cnum| tcx.missing_lang_items(cnum))
.filter(|l| l.is_weak())
.filter_map(|&l| {
let name = l.link_name()?;
lang_items::required(tcx, l).then_some(name)
let export_kind = match l.target() {
Target::Fn => SymbolExportKind::Text,
Target::Static => SymbolExportKind::Data,
_ => bug!(
"Don't know what the export kind is for lang item of kind {:?}",
l.target()
),
};
lang_items::required(tcx, l).then_some((name, export_kind))
})
.collect();
let prefix = match (target.is_like_windows, target.arch.as_ref()) {
(true, "x86") => "_",
(true, "arm64ec") => "#",
_ => "",
};
// This loop only adds new items to values of the hash map, so the order in which we
// iterate over the values is not important.
@@ -1065,10 +1079,13 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
.for_each(|(_, linked_symbols)| {
let mut symbols = missing_weak_lang_items
.iter()
.map(|item| {
.map(|(item, export_kind)| {
(
format!("{prefix}{}", mangle_internal_symbol(tcx, item.as_str())),
SymbolExportKind::Text,
add_prefix(
mangle_internal_symbol(tcx, item.as_str()),
*export_kind,
),
*export_kind,
)
})
.collect::<Vec<_>>();
@@ -1083,12 +1100,12 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
// errors.
linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| {
(
format!(
"{prefix}{}",
add_prefix(
mangle_internal_symbol(
tcx,
global_fn_name(method.name).as_str()
)
global_fn_name(method.name).as_str(),
),
SymbolExportKind::Text,
),
SymbolExportKind::Text,
)
@@ -387,7 +387,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
[sym::arm, sym::a32 | sym::t32]
if !tcx.sess.target.has_thumb_interworking =>
{
tcx.dcx().emit_err(errors::UnsuportedInstructionSet {
tcx.dcx().emit_err(errors::UnsupportedInstructionSet {
span: attr.span(),
});
None
-1
View File
@@ -61,7 +61,6 @@ pub enum AtomicRmwBinOp {
#[derive(Copy, Clone, Debug)]
pub enum AtomicOrdering {
Unordered,
Relaxed,
Acquire,
Release,
+1 -1
View File
@@ -149,7 +149,7 @@ pub(crate) struct NullOnExport {
#[derive(Diagnostic)]
#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)]
pub(crate) struct UnsuportedInstructionSet {
pub(crate) struct UnsupportedInstructionSet {
#[primary_span]
pub span: Span,
}
+1 -2
View File
@@ -2,7 +2,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@@ -219,7 +218,7 @@ pub struct CrateInfo {
pub target_cpu: String,
pub target_features: Vec<String>,
pub crate_types: Vec<CrateType>,
pub exported_symbols: UnordMap<CrateType, Vec<String>>,
pub exported_symbols: UnordMap<CrateType, Vec<(String, SymbolExportKind)>>,
pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
pub local_crate_name: Symbol,
pub compiler_builtins: Option<CrateNum>,
@@ -336,7 +336,6 @@ pub fn codegen_intrinsic_call(
};
let parse_ordering = |bx: &Bx, s| match s {
"unordered" => Unordered,
"relaxed" => Relaxed,
"acquire" => Acquire,
"release" => Release,
@@ -493,11 +493,21 @@ pub fn eval_intrinsic(
sym::minnumf64 => self.float_min_intrinsic::<Double>(args, dest)?,
sym::minnumf128 => self.float_min_intrinsic::<Quad>(args, dest)?,
sym::minimumf16 => self.float_minimum_intrinsic::<Half>(args, dest)?,
sym::minimumf32 => self.float_minimum_intrinsic::<Single>(args, dest)?,
sym::minimumf64 => self.float_minimum_intrinsic::<Double>(args, dest)?,
sym::minimumf128 => self.float_minimum_intrinsic::<Quad>(args, dest)?,
sym::maxnumf16 => self.float_max_intrinsic::<Half>(args, dest)?,
sym::maxnumf32 => self.float_max_intrinsic::<Single>(args, dest)?,
sym::maxnumf64 => self.float_max_intrinsic::<Double>(args, dest)?,
sym::maxnumf128 => self.float_max_intrinsic::<Quad>(args, dest)?,
sym::maximumf16 => self.float_maximum_intrinsic::<Half>(args, dest)?,
sym::maximumf32 => self.float_maximum_intrinsic::<Single>(args, dest)?,
sym::maximumf64 => self.float_maximum_intrinsic::<Double>(args, dest)?,
sym::maximumf128 => self.float_maximum_intrinsic::<Quad>(args, dest)?,
sym::copysignf16 => self.float_copysign_intrinsic::<Half>(args, dest)?,
sym::copysignf32 => self.float_copysign_intrinsic::<Single>(args, dest)?,
sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?,
@@ -830,6 +840,38 @@ fn float_max_intrinsic<F>(
interp_ok(())
}
fn float_minimum_intrinsic<F>(
&mut self,
args: &[OpTy<'tcx, M::Provenance>],
dest: &MPlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ()>
where
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
{
let a: F = self.read_scalar(&args[0])?.to_float()?;
let b: F = self.read_scalar(&args[1])?.to_float()?;
let res = a.minimum(b);
let res = self.adjust_nan(res, &[a, b]);
self.write_scalar(res, dest)?;
interp_ok(())
}
fn float_maximum_intrinsic<F>(
&mut self,
args: &[OpTy<'tcx, M::Provenance>],
dest: &MPlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ()>
where
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
{
let a: F = self.read_scalar(&args[0])?.to_float()?;
let b: F = self.read_scalar(&args[1])?.to_float()?;
let res = a.maximum(b);
let res = self.adjust_nan(res, &[a, b]);
self.write_scalar(res, dest)?;
interp_ok(())
}
fn float_copysign_intrinsic<F>(
&mut self,
args: &[OpTy<'tcx, M::Provenance>],
-1
View File
@@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(assert_matches)]
#![feature(box_patterns)]
-1
View File
@@ -7,7 +7,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(decl_macro)]
-1
View File
@@ -7,7 +7,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
+12 -18
View File
@@ -1,4 +1,3 @@
use std::ops::Deref;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
@@ -1117,7 +1116,6 @@ enum AddSemicolon {
/// of functionality used by `InvocationCollector`.
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
type OutputTy = SmallVec<[Self; 1]>;
type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec;
type ItemKind = ItemKind;
const KIND: AstFragmentKind;
fn to_annotatable(self) -> Annotatable;
@@ -1134,7 +1132,7 @@ fn walk<V: MutVisitor>(&mut self, _visitor: &mut V) {
fn is_mac_call(&self) -> bool {
false
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
unreachable!()
}
fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
@@ -1189,7 +1187,7 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1345,7 +1343,7 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1386,7 +1384,7 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1427,7 +1425,7 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let item = self.wrapped.into_inner();
match item.kind {
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
@@ -1465,7 +1463,7 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ForeignItemKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ForeignItemKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1579,7 +1577,6 @@ fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
}
impl InvocationCollectorNode for ast::Stmt {
type AttrsTy = ast::AttrVec;
const KIND: AstFragmentKind = AstFragmentKind::Stmts;
fn to_annotatable(self) -> Annotatable {
Annotatable::Stmt(P(self))
@@ -1599,7 +1596,7 @@ fn is_mac_call(&self) -> bool {
StmtKind::Let(..) | StmtKind::Empty => false,
}
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
// We pull macro invocations (both attributes and fn-like macro calls) out of their
// `StmtKind`s and treat them as statement macro invocations, not as items or expressions.
let (add_semicolon, mac, attrs) = match self.kind {
@@ -1693,7 +1690,7 @@ fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ast::TyKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.into_inner();
match node.kind {
TyKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
@@ -1717,7 +1714,7 @@ fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
fn is_mac_call(&self) -> bool {
matches!(self.kind, PatKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.into_inner();
match node.kind {
PatKind::MacCall(mac) => (mac, AttrVec::new(), AddSemicolon::No),
@@ -1728,7 +1725,6 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
impl InvocationCollectorNode for P<ast::Expr> {
type OutputTy = P<ast::Expr>;
type AttrsTy = ast::AttrVec;
const KIND: AstFragmentKind = AstFragmentKind::Expr;
fn to_annotatable(self) -> Annotatable {
Annotatable::Expr(self)
@@ -1745,7 +1741,7 @@ fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
fn is_mac_call(&self) -> bool {
matches!(self.kind, ExprKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.into_inner();
match node.kind {
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1757,7 +1753,6 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
struct OptExprTag;
impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
type OutputTy = Option<P<ast::Expr>>;
type AttrsTy = ast::AttrVec;
const KIND: AstFragmentKind = AstFragmentKind::OptExpr;
fn to_annotatable(self) -> Annotatable {
Annotatable::Expr(self.wrapped)
@@ -1772,7 +1767,7 @@ fn walk_flat_map<V: MutVisitor>(mut self, visitor: &mut V) -> Self::OutputTy {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.wrapped.into_inner();
match node.kind {
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
@@ -1794,7 +1789,6 @@ fn dummy() -> MethodReceiverTag {
}
impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag> {
type OutputTy = Self;
type AttrsTy = ast::AttrVec;
const KIND: AstFragmentKind = AstFragmentKind::MethodReceiverExpr;
fn descr() -> &'static str {
"an expression"
@@ -1811,7 +1805,7 @@ fn walk<V: MutVisitor>(&mut self, visitor: &mut V) {
fn is_mac_call(&self) -> bool {
matches!(self.wrapped.kind, ast::ExprKind::MacCall(..))
}
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
fn take_mac_call(self) -> (P<ast::MacCall>, ast::AttrVec, AddSemicolon) {
let node = self.wrapped.into_inner();
match node.kind {
ExprKind::MacCall(mac) => (mac, node.attrs, AddSemicolon::No),
-1
View File
@@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(rust_logo)]
#![feature(array_windows)]
#![feature(associated_type_defaults)]
+2 -2
View File
@@ -96,7 +96,7 @@ macro_rules! declare_features {
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
(accepted, cfg_attr_multi, "1.33.0", Some(54881)),
/// Allows the use of `#[cfg(<true/false>)]`.
(accepted, cfg_boolean_literals, "CURRENT_RUSTC_VERSION", Some(131204)),
(accepted, cfg_boolean_literals, "1.88.0", Some(131204)),
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
(accepted, cfg_doctest, "1.40.0", Some(62210)),
/// Enables `#[cfg(panic = "...")]` config key.
@@ -301,7 +301,7 @@ macro_rules! declare_features {
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(accepted, move_ref_pattern, "1.49.0", Some(68354)),
/// Allows using `#[naked]` on functions.
(accepted, naked_functions, "CURRENT_RUSTC_VERSION", Some(90957)),
(accepted, naked_functions, "1.88.0", Some(90957)),
/// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
(accepted, native_link_modifiers, "1.61.0", Some(81490)),
/// Allows specifying the bundle link modifier
+1 -1
View File
@@ -143,7 +143,7 @@ macro_rules! declare_features {
(removed, infer_static_outlives_requirements, "1.63.0", Some(54185),
Some("removed as it caused some confusion and discussion was inactive for years")),
/// Allow anonymous constants from an inline `const` block in pattern position
(removed, inline_const_pat, "CURRENT_RUSTC_VERSION", Some(76001),
(removed, inline_const_pat, "1.88.0", Some(76001),
Some("removed due to implementation concerns as it requires significant refactorings")),
/// Lazily evaluate constants. This allows constants to depend on type parameters.
(removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
+10 -10
View File
@@ -206,7 +206,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind
(internal, cfg_emscripten_wasm_eh, "1.86.0", None),
/// Allows checking whether or not the backend correctly supports unstable float types.
(internal, cfg_target_has_reliable_f16_f128, "CURRENT_RUSTC_VERSION", None),
(internal, cfg_target_has_reliable_f16_f128, "1.88.0", None),
/// Allows identifying the `compiler_builtins` crate.
(internal, compiler_builtins, "1.13.0", None),
/// Allows writing custom MIR
@@ -316,7 +316,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
// Unstable `#[target_feature]` directives.
(unstable, aarch64_unstable_target_feature, "1.82.0", Some(44839)),
(unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
(unstable, apx_target_feature, "CURRENT_RUSTC_VERSION", Some(139284)),
(unstable, apx_target_feature, "1.88.0", Some(139284)),
(unstable, arm_target_feature, "1.27.0", Some(44839)),
(unstable, avx512_target_feature, "1.27.0", Some(44839)),
(unstable, bpf_target_feature, "1.54.0", Some(44839)),
@@ -327,7 +327,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
(unstable, loongarch_target_feature, "1.73.0", Some(44839)),
(unstable, m68k_target_feature, "1.85.0", Some(134328)),
(unstable, mips_target_feature, "1.27.0", Some(44839)),
(unstable, movrs_target_feature, "CURRENT_RUSTC_VERSION", Some(137976)),
(unstable, movrs_target_feature, "1.88.0", Some(137976)),
(unstable, powerpc_target_feature, "1.27.0", Some(44839)),
(unstable, prfchw_target_feature, "1.78.0", Some(44839)),
(unstable, riscv_target_feature, "1.45.0", Some(44839)),
@@ -385,7 +385,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows associated type defaults.
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
/// Allows implementing `AsyncDrop`.
(incomplete, async_drop, "CURRENT_RUSTC_VERSION", Some(126482)),
(incomplete, async_drop, "1.88.0", Some(126482)),
/// Allows async functions to be called from `dyn Trait`.
(incomplete, async_fn_in_dyn_trait, "1.85.0", Some(133119)),
/// Allows `#[track_caller]` on async functions.
@@ -395,7 +395,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows `async` trait bound modifier.
(unstable, async_trait_bounds, "1.85.0", Some(62290)),
/// Allows using Intel AVX10 target features and intrinsics
(unstable, avx10_target_feature, "CURRENT_RUSTC_VERSION", Some(138843)),
(unstable, avx10_target_feature, "1.88.0", Some(138843)),
/// Allows using C-variadics.
(unstable, c_variadic, "1.34.0", Some(44930)),
/// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
@@ -483,11 +483,11 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows exhaustive pattern matching on types that contain uninhabited types.
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
/// Disallows `extern` without an explicit ABI.
(unstable, explicit_extern_abis, "CURRENT_RUSTC_VERSION", Some(134986)),
(unstable, explicit_extern_abis, "1.88.0", Some(134986)),
/// Allows explicit tail calls via `become` expression.
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
/// Allows using `#[export_stable]` which indicates that an item is exportable.
(incomplete, export_stable, "CURRENT_RUSTC_VERSION", Some(139939)),
(incomplete, export_stable, "1.88.0", Some(139939)),
/// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
/// for functions with varargs.
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
@@ -512,7 +512,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows impls for the Freeze trait.
(internal, freeze_impls, "1.78.0", Some(121675)),
/// Frontmatter `---` blocks for use by external tools.
(unstable, frontmatter, "CURRENT_RUSTC_VERSION", Some(136889)),
(unstable, frontmatter, "1.88.0", Some(136889)),
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
@@ -575,7 +575,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on `extern "Rust"` functions.
(unstable, naked_functions_rustic_abi, "CURRENT_RUSTC_VERSION", Some(138997)),
(unstable, naked_functions_rustic_abi, "1.88.0", Some(138997)),
/// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.
(unstable, naked_functions_target_feature, "1.86.0", Some(138568)),
/// Allows specifying the as-needed link modifier
@@ -641,7 +641,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
/// Allows string patterns to dereference values to match them.
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
/// Allows `super let` statements.
(unstable, super_let, "CURRENT_RUSTC_VERSION", Some(139076)),
(unstable, super_let, "1.88.0", Some(139076)),
/// Allows subtrait items to shadow supertrait items.
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
/// Allows using `#[thread_local]` on `static` items.
@@ -25,9 +25,6 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
path.to_path_buf()
} else {
// `/a/b/c/foo/bar.rs` contains the current macro invocation
#[cfg(bootstrap)]
let mut source_file_path = span.source_file().path();
#[cfg(not(bootstrap))]
let mut source_file_path = span.local_file().unwrap();
// `/a/b/c/foo/`
source_file_path.pop();
+8 -7
View File
@@ -309,6 +309,8 @@ pub enum DefPathData {
/// An existential `impl Trait` type node.
/// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
OpaqueTy,
/// Used for remapped captured lifetimes in an existential `impl Trait` type node.
OpaqueLifetime(Symbol),
/// An anonymous associated type from an RPITIT. The symbol refers to the name of the method
/// that defined the type.
AnonAssocTy(Symbol),
@@ -445,7 +447,8 @@ impl DefPathData {
pub fn get_opt_name(&self) -> Option<Symbol> {
use self::DefPathData::*;
match *self {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
| OpaqueLifetime(name) => Some(name),
Impl
| ForeignMod
@@ -465,9 +468,8 @@ pub fn get_opt_name(&self) -> Option<Symbol> {
fn hashed_symbol(&self) -> Option<Symbol> {
use self::DefPathData::*;
match *self {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => {
Some(name)
}
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
| OpaqueLifetime(name) => Some(name),
Impl
| ForeignMod
@@ -486,9 +488,8 @@ fn hashed_symbol(&self) -> Option<Symbol> {
pub fn name(&self) -> DefPathDataName {
use self::DefPathData::*;
match *self {
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => {
DefPathDataName::Named(name)
}
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
| OpaqueLifetime(name) => DefPathDataName::Named(name),
// Note that this does not show up in user print-outs.
CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
Impl => DefPathDataName::Anon { namespace: kw::Impl },
+8 -15
View File
@@ -50,21 +50,14 @@ fn trait_object_roundtrips() {
}
fn trait_object_roundtrips_impl(syntax: TraitObjectSyntax) {
let unambig = TyKind::TraitObject::<'_, ()>(
&[],
TaggedRef::new(
&const {
Lifetime {
hir_id: HirId::INVALID,
ident: Ident::new(sym::name, DUMMY_SP),
kind: LifetimeKind::Static,
source: LifetimeSource::Other,
syntax: LifetimeSyntax::Hidden,
}
},
syntax,
),
);
let lt = Lifetime {
hir_id: HirId::INVALID,
ident: Ident::new(sym::name, DUMMY_SP),
kind: LifetimeKind::Static,
source: LifetimeSource::Other,
syntax: LifetimeSyntax::Hidden,
};
let unambig = TyKind::TraitObject::<'_, ()>(&[], TaggedRef::new(&lt, syntax));
let unambig_to_ambig = unsafe { std::mem::transmute::<_, TyKind<'_, AmbigArg>>(unambig) };
match unambig_to_ambig {
-1
View File
@@ -4,7 +4,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]
+1 -1
View File
@@ -522,7 +522,7 @@ hir_analysis_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_analysis_traits_with_defualt_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
hir_analysis_traits_with_default_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
.note = a trait object implements `{$traits}` if and only if `{$traits}` is one of the trait object's trait bounds
hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number}
@@ -5,7 +5,7 @@
use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
@@ -14,10 +14,10 @@
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{
self, BottomUpFolder, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast,
TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
};
use rustc_middle::{bug, span_bug};
use rustc_span::Span;
use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -1137,65 +1137,319 @@ fn check_region_bounds_on_impl_item<'tcx>(
// but found 0" it's confusing, because it looks like there
// are zero. Since I don't quite know how to phrase things at
// the moment, give a kind of vague error message.
if trait_params != impl_params {
let span = tcx
.hir_get_generics(impl_m.def_id.expect_local())
.expect("expected impl item to have generics or else we can't compare them")
.span;
if trait_params == impl_params {
return Ok(());
}
let mut generics_span = None;
let mut bounds_span = vec![];
let mut where_span = None;
if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
&& let Some(trait_generics) = trait_node.generics()
{
generics_span = Some(trait_generics.span);
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
// *are* present in the impl.
for p in trait_generics.predicates {
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
for b in pred.bounds {
if !delay && let Some(guar) = check_region_late_boundedness(tcx, impl_m, trait_m) {
return Err(guar);
}
let span = tcx
.hir_get_generics(impl_m.def_id.expect_local())
.expect("expected impl item to have generics or else we can't compare them")
.span;
let mut generics_span = None;
let mut bounds_span = vec![];
let mut where_span = None;
if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
&& let Some(trait_generics) = trait_node.generics()
{
generics_span = Some(trait_generics.span);
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
// *are* present in the impl.
for p in trait_generics.predicates {
match p.kind {
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bounds,
..
})
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
bounds,
..
}) => {
for b in *bounds {
if let hir::GenericBound::Outlives(lt) = b {
bounds_span.push(lt.ident.span);
}
}
}
_ => {}
}
if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
&& let Some(impl_generics) = impl_node.generics()
{
let mut impl_bounds = 0;
for p in impl_generics.predicates {
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
for b in pred.bounds {
}
if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
&& let Some(impl_generics) = impl_node.generics()
{
let mut impl_bounds = 0;
for p in impl_generics.predicates {
match p.kind {
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bounds,
..
})
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
bounds,
..
}) => {
for b in *bounds {
if let hir::GenericBound::Outlives(_) = b {
impl_bounds += 1;
}
}
}
}
if impl_bounds == bounds_span.len() {
bounds_span = vec![];
} else if impl_generics.has_where_clause_predicates {
where_span = Some(impl_generics.where_clause_span);
_ => {}
}
}
if impl_bounds == bounds_span.len() {
bounds_span = vec![];
} else if impl_generics.has_where_clause_predicates {
where_span = Some(impl_generics.where_clause_span);
}
}
let reported = tcx
.dcx()
.create_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind: impl_m.descr(),
ident: impl_m.ident(tcx),
generics_span,
bounds_span,
where_span,
})
.emit_unless(delay);
return Err(reported);
}
Ok(())
let reported = tcx
.dcx()
.create_err(LifetimesOrBoundsMismatchOnTrait {
span,
item_kind: impl_m.descr(),
ident: impl_m.ident(tcx),
generics_span,
bounds_span,
where_span,
})
.emit_unless(delay);
Err(reported)
}
#[allow(unused)]
enum LateEarlyMismatch<'tcx> {
EarlyInImpl(DefId, DefId, ty::Region<'tcx>),
LateInImpl(DefId, DefId, ty::Region<'tcx>),
}
fn check_region_late_boundedness<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
) -> Option<ErrorGuaranteed> {
if !impl_m.is_fn() {
return None;
}
let (infcx, param_env) = tcx
.infer_ctxt()
.build_with_typing_env(ty::TypingEnv::non_body_analysis(tcx, impl_m.def_id));
let impl_m_args = infcx.fresh_args_for_item(DUMMY_SP, impl_m.def_id);
let impl_m_sig = tcx.fn_sig(impl_m.def_id).instantiate(tcx, impl_m_args);
let impl_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, impl_m_sig);
let trait_m_args = infcx.fresh_args_for_item(DUMMY_SP, trait_m.def_id);
let trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_args);
let trait_m_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_m_sig);
let ocx = ObligationCtxt::new(&infcx);
// Equate the signatures so that we can infer whether a late-bound param was present where
// an early-bound param was expected, since we replace the late-bound lifetimes with
// `ReLateParam`, and early-bound lifetimes with infer vars, so the early-bound args will
// resolve to `ReLateParam` if there is a mismatch.
let Ok(()) = ocx.eq(
&ObligationCause::dummy(),
param_env,
ty::Binder::dummy(trait_m_sig),
ty::Binder::dummy(impl_m_sig),
) else {
return None;
};
let errors = ocx.select_where_possible();
if !errors.is_empty() {
return None;
}
let mut mismatched = vec![];
let impl_generics = tcx.generics_of(impl_m.def_id);
for (id_arg, arg) in
std::iter::zip(ty::GenericArgs::identity_for_item(tcx, impl_m.def_id), impl_m_args)
{
if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
&& let ty::ReVar(vid) = r.kind()
&& let r = infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(tcx, vid)
&& let ty::ReLateParam(ty::LateParamRegion {
kind: ty::LateParamRegionKind::Named(trait_param_def_id, _),
..
}) = r.kind()
&& let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
{
mismatched.push(LateEarlyMismatch::EarlyInImpl(
impl_generics.region_param(ebr, tcx).def_id,
trait_param_def_id,
id_arg.expect_region(),
));
}
}
let trait_generics = tcx.generics_of(trait_m.def_id);
for (id_arg, arg) in
std::iter::zip(ty::GenericArgs::identity_for_item(tcx, trait_m.def_id), trait_m_args)
{
if let ty::GenericArgKind::Lifetime(r) = arg.unpack()
&& let ty::ReVar(vid) = r.kind()
&& let r = infcx
.inner
.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(tcx, vid)
&& let ty::ReLateParam(ty::LateParamRegion {
kind: ty::LateParamRegionKind::Named(impl_param_def_id, _),
..
}) = r.kind()
&& let ty::ReEarlyParam(ebr) = id_arg.expect_region().kind()
{
mismatched.push(LateEarlyMismatch::LateInImpl(
impl_param_def_id,
trait_generics.region_param(ebr, tcx).def_id,
id_arg.expect_region(),
));
}
}
if mismatched.is_empty() {
return None;
}
let spans: Vec<_> = mismatched
.iter()
.map(|param| {
let (LateEarlyMismatch::EarlyInImpl(impl_param_def_id, ..)
| LateEarlyMismatch::LateInImpl(impl_param_def_id, ..)) = param;
tcx.def_span(impl_param_def_id)
})
.collect();
let mut diag = tcx
.dcx()
.struct_span_err(spans, "lifetime parameters do not match the trait definition")
.with_note("lifetime parameters differ in whether they are early- or late-bound")
.with_code(E0195);
for mismatch in mismatched {
match mismatch {
LateEarlyMismatch::EarlyInImpl(
impl_param_def_id,
trait_param_def_id,
early_bound_region,
) => {
let mut multispan = MultiSpan::from_spans(vec![
tcx.def_span(impl_param_def_id),
tcx.def_span(trait_param_def_id),
]);
multispan
.push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
multispan
.push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
multispan.push_span_label(
tcx.def_span(impl_param_def_id),
format!("`{}` is early-bound", tcx.item_name(impl_param_def_id)),
);
multispan.push_span_label(
tcx.def_span(trait_param_def_id),
format!("`{}` is late-bound", tcx.item_name(trait_param_def_id)),
);
if let Some(span) =
find_region_in_predicates(tcx, impl_m.def_id, early_bound_region)
{
multispan.push_span_label(
span,
format!(
"this lifetime bound makes `{}` early-bound",
tcx.item_name(impl_param_def_id)
),
);
}
diag.span_note(
multispan,
format!(
"`{}` differs between the trait and impl",
tcx.item_name(impl_param_def_id)
),
);
}
LateEarlyMismatch::LateInImpl(
impl_param_def_id,
trait_param_def_id,
early_bound_region,
) => {
let mut multispan = MultiSpan::from_spans(vec![
tcx.def_span(impl_param_def_id),
tcx.def_span(trait_param_def_id),
]);
multispan
.push_span_label(tcx.def_span(tcx.parent(impl_m.def_id)), "in this impl...");
multispan
.push_span_label(tcx.def_span(tcx.parent(trait_m.def_id)), "in this trait...");
multispan.push_span_label(
tcx.def_span(impl_param_def_id),
format!("`{}` is late-bound", tcx.item_name(impl_param_def_id)),
);
multispan.push_span_label(
tcx.def_span(trait_param_def_id),
format!("`{}` is early-bound", tcx.item_name(trait_param_def_id)),
);
if let Some(span) =
find_region_in_predicates(tcx, trait_m.def_id, early_bound_region)
{
multispan.push_span_label(
span,
format!(
"this lifetime bound makes `{}` early-bound",
tcx.item_name(trait_param_def_id)
),
);
}
diag.span_note(
multispan,
format!(
"`{}` differs between the trait and impl",
tcx.item_name(impl_param_def_id)
),
);
}
}
}
Some(diag.emit())
}
fn find_region_in_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
early_bound_region: ty::Region<'tcx>,
) -> Option<Span> {
for (pred, span) in tcx.explicit_predicates_of(def_id).instantiate_identity(tcx) {
if pred.visit_with(&mut FindRegion(early_bound_region)).is_break() {
return Some(span);
}
}
struct FindRegion<'tcx>(ty::Region<'tcx>);
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindRegion<'tcx> {
type Result = ControlFlow<()>;
fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
if r == self.0 { ControlFlow::Break(()) } else { ControlFlow::Continue(()) }
}
}
None
}
#[instrument(level = "debug", skip(infcx))]
@@ -103,10 +103,18 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::minnumf32
| sym::minnumf64
| sym::minnumf128
| sym::minimumf16
| sym::minimumf32
| sym::minimumf64
| sym::minimumf128
| sym::maxnumf16
| sym::maxnumf32
| sym::maxnumf64
| sym::maxnumf128
| sym::maximumf16
| sym::maximumf32
| sym::maximumf64
| sym::maximumf128
| sym::rustc_peek
| sym::type_name
| sym::forget
@@ -374,11 +382,21 @@ pub(crate) fn check_intrinsic_type(
sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
sym::maximumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
sym::maximumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
sym::copysignf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
sym::copysignf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
sym::copysignf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
@@ -14,7 +14,7 @@
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DisambiguatorState;
use rustc_hir::definitions::{DefPathData, DisambiguatorState};
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
use rustc_hir::{
self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
@@ -1470,14 +1470,14 @@ fn remap_opaque_captures(
let mut captures = captures.borrow_mut();
let remapped = *captures.entry(lifetime).or_insert_with(|| {
// `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once
// per `resolve_bound_vars` query. This is the only location that creates nested
// lifetime inside a opaque type. `<opaque_def_id>::LifetimeNs(..)` is thus unique
// per `resolve_bound_vars` query. This is the only location that creates
// `OpaqueLifetime` paths. `<opaque_def_id>::OpaqueLifetime(..)` is thus unique
// to this query and duplicates within the query are handled by `self.disambiguator`.
let feed = self.tcx.create_def(
opaque_def_id,
Some(ident.name),
DefKind::LifetimeParam,
None,
DefKind::LifetimeParam,
Some(DefPathData::OpaqueLifetime(ident.name)),
&mut self.disambiguator,
);
feed.def_span(ident.span);
+1 -1
View File
@@ -1327,7 +1327,7 @@ pub(crate) struct ImplForTyRequires {
}
#[derive(Diagnostic)]
#[diag(hir_analysis_traits_with_defualt_impl, code = E0321)]
#[diag(hir_analysis_traits_with_default_impl, code = E0321)]
#[note]
pub(crate) struct TraitsWithDefaultImpl<'a> {
#[primary_span]
@@ -9,8 +9,8 @@
use rustc_hir::{AmbigArg, HirId};
use rustc_middle::bug;
use rustc_middle::ty::{
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor, Upcast,
self as ty, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, Upcast,
};
use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
use rustc_trait_selection::traits;
@@ -996,7 +996,7 @@ struct GenericParamAndBoundVarCollector<'a, 'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 'tcx> {
type Result = ControlFlow<ErrorGuaranteed>;
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
&mut self,
binder: &ty::Binder<'tcx, T>,
) -> Self::Result {
@@ -172,7 +172,14 @@ pub(super) fn lower_trait_object_ty(
let principal_trait = regular_traits.into_iter().next();
let mut needed_associated_types = vec![];
// A stable ordering of associated types from the principal trait and all its
// supertraits. We use this to ensure that different substitutions of a trait
// don't result in `dyn Trait` types with different projections lists, which
// can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
// We achieve a stable ordering by walking over the unsubstituted principal
// trait ref.
let mut ordered_associated_types = vec![];
if let Some((principal_trait, ref spans)) = principal_trait {
let principal_trait = principal_trait.map_bound(|trait_pred| {
assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive);
@@ -197,16 +204,13 @@ pub(super) fn lower_trait_object_ty(
// FIXME(negative_bounds): Handle this correctly...
let trait_ref =
tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
needed_associated_types.extend(
ordered_associated_types.extend(
tcx.associated_items(pred.trait_ref.def_id)
.in_definition_order()
// We only care about associated types.
.filter(|item| item.is_type())
// No RPITITs -- they're not dyn-compatible for now.
.filter(|item| !item.is_impl_trait_in_trait())
// If the associated type has a `where Self: Sized` bound,
// we do not need to constrain the associated type.
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
.map(|item| (item.def_id, trait_ref)),
);
}
@@ -278,14 +282,26 @@ pub(super) fn lower_trait_object_ty(
}
}
// We compute the list of projection bounds taking the ordered associated types,
// and check if there was an entry in the collected `projection_bounds`. Those
// are computed by first taking the user-written associated types, then elaborating
// the principal trait ref, and only using those if there was no user-written.
// See note below about how we handle missing associated types with `Self: Sized`,
// which are not required to be provided, but are still used if they are provided.
let mut missing_assoc_types = FxIndexSet::default();
let projection_bounds: Vec<_> = needed_associated_types
let projection_bounds: Vec<_> = ordered_associated_types
.into_iter()
.filter_map(|key| {
if let Some(assoc) = projection_bounds.get(&key) {
Some(*assoc)
} else {
missing_assoc_types.insert(key);
// If the associated type has a `where Self: Sized` bound, then
// we do not need to provide the associated type. This results in
// a `dyn Trait` type that has a different number of projection
// bounds, which may lead to type mismatches.
if !tcx.generics_require_sized_self(key.0) {
missing_assoc_types.insert(key);
}
None
}
})
-5
View File
@@ -59,7 +59,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
@@ -223,10 +222,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
_ => (),
}
});
tcx.par_hir_body_owners(|item_def_id| {
let def_kind = tcx.def_kind(item_def_id);
// Skip `AnonConst`s because we feed their `type_of`.
if !matches!(def_kind, DefKind::AnonConst) {
tcx.ensure_ok().typeck(item_def_id);
-1
View File
@@ -2,7 +2,6 @@
//! the definitions in this file have equivalents in `rustc_ast_pretty`.
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![recursion_limit = "256"]
// tidy-alphabetical-end
@@ -2339,7 +2339,7 @@ struct MismatchedParam<'a> {
}
if !mismatched_params.is_empty() {
// For each mismatched paramter, create a two-way link to each matched parameter
// For each mismatched parameter, create a two-way link to each matched parameter
// of the same type.
let mut dependants = IndexVec::<ExpectedIdx, _>::from_fn_n(
|_| SmallVec::<[u32; 4]>::new(),
+2 -4
View File
@@ -1,7 +1,6 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
@@ -32,6 +31,7 @@
mod intrinsicck;
mod method;
mod op;
mod opaque_types;
mod pat;
mod place_op;
mod rvalue_scopes;
@@ -245,9 +245,7 @@ fn typeck_with_inspect<'tcx>(
let typeck_results = fcx.resolve_type_vars_in_body(body);
// We clone the defined opaque types during writeback in the new solver
// because we have to use them during normalization.
let _ = fcx.infcx.take_opaque_types();
fcx.detect_opaque_types_added_during_writeback();
// Consistency check our TypeckResults instance can hold all ItemLocalIds
// it will need to hold.
@@ -0,0 +1,26 @@
use super::FnCtxt;
impl<'tcx> FnCtxt<'_, 'tcx> {
/// We may in theory add further uses of an opaque after cloning the opaque
/// types storage during writeback when computing the defining uses.
///
/// Silently ignoring them is dangerous and could result in ICE or even in
/// unsoundness, so we make sure we catch such cases here. There's currently
/// no known code where this actually happens, even with the new solver which
/// does normalize types in writeback after cloning the opaque type storage.
///
/// FIXME(@lcnr): I believe this should be possible in theory and would like
/// an actual test here. After playing around with this for an hour, I wasn't
/// able to do anything which didn't already try to normalize the opaque before
/// then, either allowing compilation to succeed or causing an ambiguity error.
pub(super) fn detect_opaque_types_added_during_writeback(&self) {
let num_entries = self.checked_opaque_types_storage_entries.take().unwrap();
for (key, hidden_type) in
self.inner.borrow_mut().opaque_types().opaque_types_added_since(num_entries)
{
let opaque_type_string = self.tcx.def_path_str(key.def_id);
let msg = format!("unexpected cyclic definition of `{opaque_type_string}`");
self.dcx().span_delayed_bug(hidden_type.span, msg);
}
let _ = self.take_opaque_types();
}
}
+17 -9
View File
@@ -650,14 +650,13 @@ fn calc_adjust_mode(
match &pat.kind {
// Type checking these product-like types successfully always require
// that the expected type be of those types and not reference types.
PatKind::Tuple(..)
| PatKind::Range(..)
| PatKind::Slice(..) => AdjustMode::peel_all(),
PatKind::Tuple(..) | PatKind::Range(..) | PatKind::Slice(..) => AdjustMode::peel_all(),
// When checking an explicit deref pattern, only peel reference types.
// FIXME(deref_patterns): If box patterns and deref patterns need to coexist, box
// patterns may want `PeelKind::Implicit`, stopping on encountering a box.
| PatKind::Box(_)
| PatKind::Deref(_) => AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat },
PatKind::Box(_) | PatKind::Deref(_) => {
AdjustMode::Peel { kind: PeelKind::ExplicitDerefPat }
}
// A never pattern behaves somewhat like a literal or unit variant.
PatKind::Never => AdjustMode::peel_all(),
// For patterns with paths, how we peel the scrutinee depends on the path's resolution.
@@ -679,7 +678,11 @@ fn calc_adjust_mode(
&& self.tcx.features().deref_patterns()
&& !matches!(lt.kind, PatExprKind::Lit { .. })
{
span_bug!(lt.span, "FIXME(deref_patterns): adjust mode unimplemented for {:?}", lt.kind);
span_bug!(
lt.span,
"FIXME(deref_patterns): adjust mode unimplemented for {:?}",
lt.kind
);
}
// Call `resolve_vars_if_possible` here for inline const blocks.
let lit_ty = self.resolve_vars_if_possible(self.check_pat_expr_unadjusted(lt));
@@ -687,17 +690,21 @@ fn calc_adjust_mode(
if self.tcx.features().deref_patterns() {
let mut peeled_ty = lit_ty;
let mut pat_ref_layers = 0;
while let ty::Ref(_, inner_ty, mutbl) = *peeled_ty.kind() {
while let ty::Ref(_, inner_ty, mutbl) =
*self.try_structurally_resolve_type(pat.span, peeled_ty).kind()
{
// We rely on references at the head of constants being immutable.
debug_assert!(mutbl.is_not());
pat_ref_layers += 1;
peeled_ty = inner_ty;
}
AdjustMode::Peel { kind: PeelKind::Implicit { until_adt: None, pat_ref_layers } }
AdjustMode::Peel {
kind: PeelKind::Implicit { until_adt: None, pat_ref_layers },
}
} else {
if lit_ty.is_ref() { AdjustMode::Pass } else { AdjustMode::peel_all() }
}
},
}
// Ref patterns are complicated, we handle them in `check_pat_ref`.
PatKind::Ref(..)
@@ -928,6 +935,7 @@ fn check_pat_range(
// be peeled to `str` while ty here is still `&str`, if we don't
// err early here, a rather confusing unification error will be
// emitted instead).
let ty = self.try_structurally_resolve_type(expr.span, ty);
let fail =
!(ty.is_numeric() || ty.is_char() || ty.is_ty_var() || ty.references_error());
Some((fail, ty, expr.span))
@@ -1,10 +1,10 @@
use std::cell::RefCell;
use std::cell::{Cell, RefCell};
use std::ops::Deref;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, HirId, HirIdMap, LangItem};
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use rustc_infer::infer::{InferCtxt, InferOk, OpaqueTypeStorageEntries, TyCtxtInferExt};
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode};
use rustc_span::Span;
@@ -37,6 +37,11 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>>,
// Used to detect opaque types uses added after we've already checked them.
//
// See [FnCtxt::detect_opaque_types_added_during_writeback] for more details.
pub(super) checked_opaque_types_storage_entries: Cell<Option<OpaqueTypeStorageEntries>>,
/// Some additional `Sized` obligations badly affect type inference.
/// These obligations are added in a later stage of typeck.
/// Removing these may also cause additional complications, see #101066.
@@ -85,12 +90,14 @@ pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let infcx =
tcx.infer_ctxt().ignoring_regions().build(TypingMode::typeck_for_body(tcx, def_id));
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
let fulfillment_cx = RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx));
TypeckRootCtxt {
typeck_results,
fulfillment_cx: RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx)),
infcx,
typeck_results,
locals: RefCell::new(Default::default()),
fulfillment_cx,
checked_opaque_types_storage_entries: Cell::new(None),
deferred_sized_obligations: RefCell::new(Vec::new()),
deferred_call_resolutions: RefCell::new(Default::default()),
deferred_cast_checks: RefCell::new(Vec::new()),
+3 -6
View File
@@ -535,13 +535,10 @@ fn visit_opaque_types(&mut self) {
let tcx = self.tcx();
// We clone the opaques instead of stealing them here as they are still used for
// normalization in the next generation trait solver.
//
// FIXME(-Znext-solver): Opaque types defined after this would simply get dropped
// at the end of typeck. While this seems unlikely to happen in practice this
// should still get fixed. Either by preventing writeback from defining new opaque
// types or by using this function at the end of writeback and running it as a
// fixpoint.
let opaque_types = self.fcx.infcx.clone_opaque_types();
let num_entries = self.fcx.inner.borrow_mut().opaque_types().num_entries();
let prev = self.fcx.checked_opaque_types_storage_entries.replace(Some(num_entries));
debug_assert_eq!(prev, None);
for (opaque_type_key, hidden_type) in opaque_types {
let hidden_type = self.resolve(hidden_type, &hidden_type.span);
let opaque_type_key = self.resolve(opaque_type_key, &hidden_type.span);
+58 -1
View File
@@ -6,7 +6,10 @@
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
use super::{
BoundRegionConversionTime, InferCtxt, OpaqueTypeStorageEntries, RegionVariableOrigin,
SubregionOrigin,
};
impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
type Interner = TyCtxt<'tcx>;
@@ -213,4 +216,58 @@ fn equate_regions(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>, span: Span) {
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
}
type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
self.inner.borrow_mut().opaque_types().num_entries()
}
fn clone_opaque_types_lookup_table(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
}
fn clone_duplicate_opaque_types(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.inner
.borrow_mut()
.opaque_types()
.iter_duplicate_entries()
.map(|(k, h)| (k, h.ty))
.collect()
}
fn clone_opaque_types_added_since(
&self,
prev_entries: OpaqueTypeStorageEntries,
) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> {
self.inner
.borrow_mut()
.opaque_types()
.opaque_types_added_since(prev_entries)
.map(|(k, h)| (k, h.ty))
.collect()
}
fn register_hidden_type_in_storage(
&self,
opaque_type_key: ty::OpaqueTypeKey<'tcx>,
hidden_ty: Ty<'tcx>,
span: Span,
) -> Option<Ty<'tcx>> {
self.register_hidden_type_in_storage(
opaque_type_key,
ty::OpaqueHiddenType { span, ty: hidden_ty },
)
}
fn add_duplicate_opaque_type(
&self,
opaque_type_key: ty::OpaqueTypeKey<'tcx>,
hidden_ty: Ty<'tcx>,
span: Span,
) {
self.inner
.borrow_mut()
.opaque_types()
.add_duplicate(opaque_type_key, ty::OpaqueHiddenType { span, ty: hidden_ty })
}
fn reset_opaque_types(&self) {
let _ = self.take_opaque_types();
}
}
+1 -1
View File
@@ -9,7 +9,7 @@
pub use freshen::TypeFreshener;
use lexical_region_resolve::LexicalRegionResolutions;
pub use lexical_region_resolve::RegionResolutionError;
use opaque_types::OpaqueTypeStorage;
pub use opaque_types::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
use region_constraints::{
GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
};
@@ -18,7 +18,7 @@
mod table;
pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
pub use table::{OpaqueTypeStorage, OpaqueTypeStorageEntries, OpaqueTypeTable};
impl<'tcx> InferCtxt<'tcx> {
/// This is a backwards compatibility hack to prevent breaking changes from
@@ -14,6 +14,16 @@ pub struct OpaqueTypeStorage<'tcx> {
duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
}
/// The number of entries in the opaque type storage at a given point.
///
/// Used to check that we haven't added any new opaque types after checking
/// the opaque types currently in the storage.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct OpaqueTypeStorageEntries {
opaque_types: usize,
duplicate_entries: usize,
}
impl<'tcx> OpaqueTypeStorage<'tcx> {
#[instrument(level = "debug")]
pub(crate) fn remove(
@@ -49,6 +59,24 @@ pub(crate) fn take_opaque_types(
std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
}
pub fn num_entries(&self) -> OpaqueTypeStorageEntries {
OpaqueTypeStorageEntries {
opaque_types: self.opaque_types.len(),
duplicate_entries: self.duplicate_entries.len(),
}
}
pub fn opaque_types_added_since(
&self,
prev_entries: OpaqueTypeStorageEntries,
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
self.opaque_types
.iter()
.skip(prev_entries.opaque_types)
.map(|(k, v)| (*k, *v))
.chain(self.duplicate_entries.iter().skip(prev_entries.duplicate_entries).copied())
}
/// Only returns the opaque types from the lookup table. These are used
/// when normalizing opaque types and have a unique key.
///
@@ -24,10 +24,6 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
where
OP: FnMut(ty::Region<'tcx>),
{
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
t.super_visit_with(self);
}
fn visit_region(&mut self, r: ty::Region<'tcx>) {
match r.kind() {
// ignore bound regions, keep visiting
-1
View File
@@ -16,7 +16,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(assert_matches)]
-1
View File
@@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(decl_macro)]
#![feature(file_buffered)]
#![feature(iter_intersperse)]
+1 -1
View File
@@ -907,7 +907,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
feed.output_filenames(Arc::new(outputs));
let res = f(tcx);
// FIXME maybe run finish even when a fatal error occured? or at least tcx.alloc_self_profile_query_strings()?
// FIXME maybe run finish even when a fatal error occurred? or at least tcx.alloc_self_profile_query_strings()?
tcx.finish();
res
},
+1 -1
View File
@@ -720,7 +720,7 @@ macro_rules! untracked {
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
untracked!(print_codegen_stats, true);
untracked!(print_llvm_passes, true);
untracked!(print_mono_items, Some(String::from("abc")));
untracked!(print_mono_items, true);
untracked!(print_type_sizes, true);
untracked!(proc_macro_backtrace, true);
untracked!(proc_macro_execution_strategy, ProcMacroExecutionStrategy::CrossThread);
@@ -49,6 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some((pat, arg)) = extract_for_loop(expr) else { return };
let arg_span = arg.span.source_callsite();
let ty = cx.typeck_results().expr_ty(arg);
let (adt, args, ref_mutability) = match ty.kind() {
@@ -78,27 +80,27 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
&& let Ok(recv_snip) = cx.sess().source_map().span_to_snippet(recv.span)
{
ForLoopsOverFalliblesLoopSub::RemoveNext {
suggestion: recv.span.between(arg.span.shrink_to_hi()),
suggestion: recv.span.between(arg_span.shrink_to_hi()),
recv_snip,
}
} else {
ForLoopsOverFalliblesLoopSub::UseWhileLet {
start_span: expr.span.with_hi(pat.span.lo()),
end_span: pat.span.between(arg.span),
end_span: pat.span.between(arg_span),
var,
}
};
let question_mark = suggest_question_mark(cx, adt, args, expr.span)
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg.span.shrink_to_hi() });
.then(|| ForLoopsOverFalliblesQuestionMark { suggestion: arg_span.shrink_to_hi() });
let suggestion = ForLoopsOverFalliblesSuggestion {
var,
start_span: expr.span.with_hi(pat.span.lo()),
end_span: pat.span.between(arg.span),
end_span: pat.span.between(arg_span),
};
cx.emit_span_lint(
FOR_LOOPS_OVER_FALLIBLES,
arg.span,
arg_span,
ForLoopsOverFalliblesDiag { article, ref_prefix, ty, sub, question_mark, suggestion },
);
}
@@ -15,7 +15,8 @@
Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys,
};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
TypeVisitor,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint::FutureIncompatibilityReason;
@@ -209,7 +210,7 @@ impl<'tcx, VarFn, OutlivesFn> TypeVisitor<TyCtxt<'tcx>>
VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>,
OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>,
{
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
// When we get into a binder, we need to add its own bound vars to the scope.
let mut added = vec![];
for arg in t.bound_vars() {
-1
View File
@@ -21,7 +21,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@@ -622,37 +622,10 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
return wrap(SI);
}
enum class LLVMRustAsmDialect {
Att,
Intel,
};
static InlineAsm::AsmDialect fromRust(LLVMRustAsmDialect Dialect) {
switch (Dialect) {
case LLVMRustAsmDialect::Att:
return InlineAsm::AD_ATT;
case LLVMRustAsmDialect::Intel:
return InlineAsm::AD_Intel;
default:
report_fatal_error("bad AsmDialect.");
}
}
extern "C" uint64_t LLVMRustGetArrayNumElements(LLVMTypeRef Ty) {
return unwrap(Ty)->getArrayNumElements();
}
extern "C" LLVMValueRef
LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen,
char *Constraints, size_t ConstraintsLen,
LLVMBool HasSideEffects, LLVMBool IsAlignStack,
LLVMRustAsmDialect Dialect, LLVMBool CanThrow) {
return wrap(InlineAsm::get(
unwrap<FunctionType>(Ty), StringRef(AsmString, AsmStringLen),
StringRef(Constraints, ConstraintsLen), HasSideEffects, IsAlignStack,
fromRust(Dialect), CanThrow));
}
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
size_t ConstraintsLen) {
// llvm::Error converts to true if it is an error.
-1
View File
@@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(rustc::default_hash_types)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(if_let_guard)]
#![feature(never_type)]
#![feature(proc_macro_diagnostic)]
+1 -1
View File
@@ -299,7 +299,7 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
let output = quote! {
const SYMBOL_DIGITS_BASE: u32 = #symbol_digits_base;
/// The number of predefined symbols; this is the the first index for
/// The number of predefined symbols; this is the first index for
/// extra pre-interned symbols in an Interner created via
/// [`Interner::with_extra_symbols`].
pub const PREDEFINED_SYMBOLS_COUNT: u32 = #predefined_symbols_count;
-1
View File
@@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(coroutines)]
-1
View File
@@ -28,7 +28,6 @@
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(allocator_api)]
@@ -22,7 +22,7 @@ pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
}
/// Kind of exported symbols.
#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable)]
#[derive(Eq, PartialEq, Debug, Copy, Clone, Encodable, Decodable, HashStable, Hash)]
pub enum SymbolExportKind {
Text,
Data,
+3
View File
@@ -1924,6 +1924,9 @@ fn async_drop_coroutine_layout(
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Option<&'tcx CoroutineLayout<'tcx>> {
if args[0].has_placeholders() || args[0].has_non_region_param() {
return None;
}
let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
self.mir_shims(instance).coroutine_layout_raw()
}
+1 -1
View File
@@ -2934,7 +2934,7 @@ pub fn pretty_wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>
fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
where
T: TypeVisitable<TyCtxt<'tcx>>,
T: TypeFoldable<TyCtxt<'tcx>>,
{
struct RegionNameCollector<'tcx> {
used_region_names: FxHashSet<Symbol>,
+4 -1
View File
@@ -723,7 +723,10 @@ pub fn new_dynamic(
repr: DynKind,
) -> Ty<'tcx> {
if cfg!(debug_assertions) {
let projection_count = obj.projection_bounds().count();
let projection_count = obj
.projection_bounds()
.filter(|item| !tcx.generics_require_sized_self(item.item_def_id()))
.count();
let expected_count: usize = obj
.principal_def_id()
.into_iter()
+2 -2
View File
@@ -66,7 +66,7 @@ impl<'tcx, F> TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F>
{
type Result = ControlFlow<()>;
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> Self::Result {
@@ -168,7 +168,7 @@ fn new(just_constrained: bool) -> Self {
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector {
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
fn visit_binder<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) {
self.current_index.shift_in(1);
t.super_visit_with(self);
self.current_index.shift_out(1);
@@ -1485,7 +1485,7 @@ pub(crate) fn clear_top_scope(&mut self, region_scope: region::Scope) {
/// panic occurred (a subset of the drops in `scope`, since we sometimes elide StorageDead and other
/// instructions on unwinding)
/// * `dropline_to`, describes the drops that would occur at this point in the code if a
/// coroutine drop occured.
/// coroutine drop occurred.
/// * `storage_dead_on_unwind`, if true, then we should emit `StorageDead` even when unwinding
/// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those)
fn build_scope_drops<'tcx, F>(
-1
View File
@@ -3,7 +3,6 @@
// tidy-alphabetical-start
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
-1
View File
@@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(assert_matches)]
#![feature(associated_type_defaults)]
#![feature(box_patterns)]
@@ -55,18 +55,45 @@ fn is_unnecessary_transmute(
},
// char → u32
(Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")),
// char (→ u32) → i32
(Char, Int(IntTy::I32)) => err(format!("u32::from({arg}).cast_signed()")),
// u32 → char
(Uint(UintTy::U32), Char) => Error {
sugg: format!("char::from_u32_unchecked({arg})"),
help: Some("consider `char::from_u32(…).unwrap()`"),
span,
},
// i32 → char
(Int(IntTy::I32), Char) => Error {
sugg: format!("char::from_u32_unchecked(i32::cast_unsigned({arg}))"),
help: Some("consider `char::from_u32(i32::cast_unsigned(…)).unwrap()`"),
span,
},
// uNN → iNN
(Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())),
// iNN → uNN
(Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())),
// fNN → xsize
(Float(ty), Uint(UintTy::Usize)) => {
err(format!("{}::to_bits({arg}) as usize", ty.name_str()))
}
(Float(ty), Int(IntTy::Isize)) => {
err(format!("{}::to_bits({arg}) as isize", ty.name_str()))
}
// fNN (→ uNN) → iNN
(Float(ty), Int(..)) => err(format!("{}::to_bits({arg}).cast_signed()", ty.name_str())),
// fNN → uNN
(Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())),
// xsize → fNN
(Uint(UintTy::Usize) | Int(IntTy::Isize), Float(ty)) => {
err(format!("{}::from_bits({arg} as _)", ty.name_str(),))
}
// iNN (→ uNN) → fNN
(Int(int_ty), Float(ty)) => err(format!(
"{}::from_bits({}::cast_unsigned({arg}))",
ty.name_str(),
int_ty.name_str()
)),
// uNN → fNN
(Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())),
// bool → { x8 }
-1
View File
@@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)]
-3
View File
@@ -60,9 +60,6 @@ monomorphize_start_not_found = using `fn main` requires the standard library
monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined
monomorphize_unknown_cgu_collection_mode =
unknown codegen-item collection mode '{$mode}', falling back to 'lazy' mode
monomorphize_wasm_c_abi_transition =
this function {$is_call ->
[true] call
@@ -64,12 +64,6 @@ pub(crate) struct EncounteredErrorWhileInstantiating {
#[help]
pub(crate) struct StartNotFound;
#[derive(Diagnostic)]
#[diag(monomorphize_unknown_cgu_collection_mode)]
pub(crate) struct UnknownCguCollectionMode<'a> {
pub mode: &'a str,
}
#[derive(Diagnostic)]
#[diag(monomorphize_abi_error_disabled_vector_type)]
#[help]
-1
View File
@@ -1,5 +1,4 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(let_chains))]
#![feature(array_windows)]
#![feature(file_buffered)]
#![feature(if_let_guard)]
@@ -124,7 +124,7 @@
use tracing::debug;
use crate::collector::{self, MonoItemCollectionStrategy, UsageMap};
use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode};
use crate::errors::{CouldntDumpMonoStats, SymbolAlreadyDefined};
struct PartitioningCx<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
@@ -1127,27 +1127,10 @@ fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I)
}
fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitions<'_> {
let collection_strategy = match tcx.sess.opts.unstable_opts.print_mono_items {
Some(ref s) => {
let mode = s.to_lowercase();
let mode = mode.trim();
if mode == "eager" {
MonoItemCollectionStrategy::Eager
} else {
if mode != "lazy" {
tcx.dcx().emit_warn(UnknownCguCollectionMode { mode });
}
MonoItemCollectionStrategy::Lazy
}
}
None => {
if tcx.sess.link_dead_code() {
MonoItemCollectionStrategy::Eager
} else {
MonoItemCollectionStrategy::Lazy
}
}
let collection_strategy = if tcx.sess.link_dead_code() {
MonoItemCollectionStrategy::Eager
} else {
MonoItemCollectionStrategy::Lazy
};
let (items, usage_map) = collector::collect_crate_mono_items(tcx, collection_strategy);
@@ -1209,7 +1192,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
}
}
if tcx.sess.opts.unstable_opts.print_mono_items.is_some() {
if tcx.sess.opts.unstable_opts.print_mono_items {
let mut item_to_cgus: UnordMap<_, Vec<_>> = Default::default();
for cgu in codegen_units {
@@ -39,13 +39,6 @@ fn well_formed_goals(
term: <Self::Interner as Interner>::Term,
) -> Option<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>>;
fn clone_opaque_types_lookup_table(
&self,
) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
fn clone_duplicate_opaque_types(
&self,
) -> Vec<(ty::OpaqueTypeKey<Self::Interner>, <Self::Interner as Interner>::Ty)>;
fn make_deduplicated_outlives_constraints(
&self,
) -> Vec<ty::OutlivesPredicate<Self::Interner, <Self::Interner as Interner>::GenericArg>>;
@@ -64,20 +57,6 @@ fn instantiate_canonical_var_with_infer(
span: <Self::Interner as Interner>::Span,
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg;
fn register_hidden_type_in_storage(
&self,
opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
hidden_ty: <Self::Interner as Interner>::Ty,
span: <Self::Interner as Interner>::Span,
) -> Option<<Self::Interner as Interner>::Ty>;
fn add_duplicate_opaque_type(
&self,
opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
hidden_ty: <Self::Interner as Interner>::Ty,
span: <Self::Interner as Interner>::Span,
);
fn add_item_bounds_for_hidden_type(
&self,
def_id: <Self::Interner as Interner>::DefId,
@@ -86,7 +65,6 @@ fn add_item_bounds_for_hidden_type(
hidden_ty: <Self::Interner as Interner>::Ty,
goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
);
fn reset_opaque_types(&self);
fn fetch_eligible_assoc_item(
&self,

Some files were not shown because too many files have changed in this diff Show More