Merge pull request #2533 from rust-lang/rustc-pull

Rustc pull update
This commit is contained in:
Tshepang Mbambo 2025-08-04 15:20:57 +02:00 committed by GitHub
commit a13caaae3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
695 changed files with 6090 additions and 3834 deletions

View file

@ -159,9 +159,6 @@ jobs:
- name: show the current environment
run: src/ci/scripts/dump-environment.sh
- name: install rust
run: src/ci/scripts/install-rust.sh
- name: install awscli
run: src/ci/scripts/install-awscli.sh

View file

@ -597,6 +597,7 @@ Sam Radhakrishnan <sk09idm@gmail.com>
Samuel Tardieu <sam@rfc1149.net>
Santiago Pastorino <spastorino@gmail.com>
Santiago Pastorino <spastorino@gmail.com> <santiago@wyeworks.com>
Sasha Pourcelot <sasha.pourcelot@protonmail.com> Sasha <sasha.pourcelot@protonmail.com>
Scott McMurray <scottmcm@users.noreply.github.com>
Scott McMurray <scottmcm@users.noreply.github.com> <smcmurray@acm.org>
Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>

View file

@ -518,9 +518,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.41"
version = "4.5.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
dependencies = [
"clap_builder",
"clap_derive",
@ -538,9 +538,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.41"
version = "4.5.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
dependencies = [
"anstream",
"anstyle",
@ -1171,7 +1171,7 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users 0.5.0",
"redox_users 0.5.2",
"windows-sys 0.60.2",
]
@ -2094,9 +2094,9 @@ dependencies = [
[[package]]
name = "jsonpath-rust"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d057f8fd19e20c3f14d3663983397155739b6bc1148dc5cd4c4a1a5b3130eb0"
checksum = "633a7320c4bb672863a3782e89b9094ad70285e097ff6832cddd0ec615beadfa"
dependencies = [
"pest",
"pest_derive",
@ -2190,7 +2190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.53.2",
"windows-targets 0.53.3",
]
[[package]]
@ -2201,9 +2201,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "libredox"
version = "0.1.6"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0"
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
dependencies = [
"bitflags",
"libc",
@ -2643,9 +2643,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.37.1"
version = "0.37.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
checksum = "b3e3d0a7419f081f4a808147e845310313a39f322d7ae1f996b7f001d6cbed04"
dependencies = [
"crc32fast",
"flate2",
@ -2653,7 +2653,7 @@ dependencies = [
"indexmap",
"memchr",
"ruzstd 0.8.1",
"wasmparser 0.234.0",
"wasmparser 0.236.0",
]
[[package]]
@ -3167,9 +3167,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.16"
version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [
"bitflags",
]
@ -3187,9 +3187,9 @@ dependencies = [
[[package]]
name = "redox_users"
version = "0.5.0"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom 0.2.16",
"libredox",
@ -3279,7 +3279,7 @@ dependencies = [
"build_helper",
"gimli 0.32.0",
"libc",
"object 0.37.1",
"object 0.37.2",
"regex",
"serde_json",
"similar",
@ -3301,9 +3301,9 @@ dependencies = [
[[package]]
name = "rustc-demangle"
version = "0.1.25"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc-hash"
@ -3417,6 +3417,7 @@ dependencies = [
"rustc_data_structures",
"rustc_macros",
"rustc_serialize",
"rustc_span",
]
[[package]]
@ -3426,7 +3427,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -3476,20 +3476,6 @@ dependencies = [
"thin-vec",
]
[[package]]
name = "rustc_attr_data_structures"
version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_data_structures",
"rustc_macros",
"rustc_serialize",
"rustc_span",
"thin-vec",
]
[[package]]
name = "rustc_attr_parsing"
version = "0.0.0"
@ -3497,7 +3483,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
@ -3553,7 +3538,6 @@ version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -3585,11 +3569,10 @@ dependencies = [
"itertools",
"libc",
"measureme",
"object 0.37.1",
"object 0.37.2",
"rustc-demangle",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_codegen_ssa",
"rustc_data_structures",
"rustc_errors",
@ -3624,13 +3607,12 @@ dependencies = [
"cc",
"itertools",
"libc",
"object 0.37.1",
"object 0.37.2",
"pathdiff",
"regex",
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -3668,7 +3650,6 @@ dependencies = [
"rustc_abi",
"rustc_apfloat",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -3814,7 +3795,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_error_codes",
"rustc_error_messages",
@ -3844,7 +3824,6 @@ dependencies = [
"rustc_ast",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -3868,8 +3847,8 @@ dependencies = [
name = "rustc_feature"
version = "0.0.0"
dependencies = [
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_hir",
"rustc_span",
"serde",
"serde_json",
@ -3914,7 +3893,7 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_ast_pretty",
"rustc_data_structures",
"rustc_hashes",
"rustc_index",
@ -3935,7 +3914,6 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -3962,7 +3940,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_hir",
"rustc_span",
]
@ -3974,7 +3951,6 @@ dependencies = [
"itertools",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -4120,7 +4096,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -4194,7 +4169,6 @@ dependencies = [
"odht",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -4230,7 +4204,6 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_error_messages",
"rustc_errors",
@ -4264,7 +4237,6 @@ dependencies = [
"rustc_apfloat",
"rustc_arena",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -4311,7 +4283,6 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
@ -4337,7 +4308,6 @@ version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -4408,7 +4378,6 @@ dependencies = [
"rustc_ast",
"rustc_ast_lowering",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -4455,7 +4424,6 @@ name = "rustc_privacy"
version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -4530,7 +4498,6 @@ dependencies = [
"parking_lot",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
@ -4557,7 +4524,6 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
@ -4676,7 +4642,7 @@ name = "rustc_target"
version = "0.0.0"
dependencies = [
"bitflags",
"object 0.37.1",
"object 0.37.2",
"rustc_abi",
"rustc_data_structures",
"rustc_fs_util",
@ -4720,7 +4686,6 @@ dependencies = [
"itertools",
"rustc_abi",
"rustc_ast",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -5074,9 +5039,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.141"
version = "1.0.142"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
dependencies = [
"itoa",
"memchr",
@ -6134,12 +6099,12 @@ dependencies = [
[[package]]
name = "wasm-encoder"
version = "0.235.0"
version = "0.236.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bc393c395cb621367ff02d854179882b9a351b4e0c93d1397e6090b53a5c2a"
checksum = "3108979166ab0d3c7262d2e16a2190ffe784b2a5beb963edef154b5e8e07680b"
dependencies = [
"leb128fmt",
"wasmparser 0.235.0",
"wasmparser 0.236.0",
]
[[package]]
@ -6179,9 +6144,9 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.235.0"
version = "0.236.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "161296c618fa2d63f6ed5fffd1112937e803cb9ec71b32b01a76321555660917"
checksum = "16d1eee846a705f6f3cb9d7b9f79b54583810f1fb57a1e3aea76d1742db2e3d2"
dependencies = [
"bitflags",
"indexmap",
@ -6190,22 +6155,22 @@ dependencies = [
[[package]]
name = "wast"
version = "235.0.0"
version = "236.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1eda4293f626c99021bb3a6fbe4fbbe90c0e31a5ace89b5f620af8925de72e13"
checksum = "11d6b6faeab519ba6fbf9b26add41617ca6f5553f99ebc33d876e591d2f4f3c6"
dependencies = [
"bumpalo",
"leb128fmt",
"memchr",
"unicode-width 0.2.1",
"wasm-encoder 0.235.0",
"wasm-encoder 0.236.0",
]
[[package]]
name = "wat"
version = "1.235.0"
version = "1.236.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e777e0327115793cb96ab220b98f85327ec3d11f34ec9e8d723264522ef206aa"
checksum = "cc31704322400f461f7f31a5f9190d5488aaeafb63ae69ad2b5888d2704dcb08"
dependencies = [
"wast",
]
@ -6461,7 +6426,7 @@ version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.2",
"windows-targets 0.53.3",
]
[[package]]
@ -6497,10 +6462,11 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.53.2"
version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",

View file

@ -23,7 +23,7 @@ use std::{cmp, fmt};
pub use GenericArgs::*;
pub use UnsafeSource::*;
pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
@ -2285,105 +2285,6 @@ pub struct FnSig {
pub span: Span,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum FloatTy {
F16,
F32,
F64,
F128,
}
impl FloatTy {
pub fn name_str(self) -> &'static str {
match self {
FloatTy::F16 => "f16",
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
FloatTy::F128 => "f128",
}
}
pub fn name(self) -> Symbol {
match self {
FloatTy::F16 => sym::f16,
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
FloatTy::F128 => sym::f128,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum IntTy {
Isize,
I8,
I16,
I32,
I64,
I128,
}
impl IntTy {
pub fn name_str(&self) -> &'static str {
match *self {
IntTy::Isize => "isize",
IntTy::I8 => "i8",
IntTy::I16 => "i16",
IntTy::I32 => "i32",
IntTy::I64 => "i64",
IntTy::I128 => "i128",
}
}
pub fn name(&self) -> Symbol {
match *self {
IntTy::Isize => sym::isize,
IntTy::I8 => sym::i8,
IntTy::I16 => sym::i16,
IntTy::I32 => sym::i32,
IntTy::I64 => sym::i64,
IntTy::I128 => sym::i128,
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
#[derive(Encodable, Decodable, HashStable_Generic)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
}
impl UintTy {
pub fn name_str(&self) -> &'static str {
match *self {
UintTy::Usize => "usize",
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
UintTy::U64 => "u64",
UintTy::U128 => "u128",
}
}
pub fn name(&self) -> Symbol {
match *self {
UintTy::Usize => sym::usize,
UintTy::U8 => sym::u8,
UintTy::U16 => sym::u16,
UintTy::U32 => sym::u32,
UintTy::U64 => sym::u64,
UintTy::U128 => sym::u128,
}
}
}
/// A constraint on an associated item.
///
/// ### Examples

View file

@ -190,15 +190,15 @@ impl fmt::Display for LitKind {
LitKind::Int(n, ty) => {
write!(f, "{n}")?;
match ty {
ast::LitIntType::Unsigned(ty) => write!(f, "{}", ty.name())?,
ast::LitIntType::Signed(ty) => write!(f, "{}", ty.name())?,
ast::LitIntType::Unsigned(ty) => write!(f, "{}", ty.name_str())?,
ast::LitIntType::Signed(ty) => write!(f, "{}", ty.name_str())?,
ast::LitIntType::Unsuffixed => {}
}
}
LitKind::Float(symbol, ty) => {
write!(f, "{symbol}")?;
match ty {
ast::LitFloatType::Suffixed(ty) => write!(f, "{}", ty.name())?,
ast::LitFloatType::Suffixed(ty) => write!(f, "{}", ty.name_str())?,
ast::LitFloatType::Unsuffixed => {}
}
}

View file

@ -8,12 +8,16 @@ edition = "2024"
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
# tidy-alphabetical-end
[features]
# tidy-alphabetical-start
default = ["nightly"]
nightly = [
"dep:rustc_serialize",
"dep:rustc_data_structures",
"dep:rustc_macros",
"dep:rustc_serialize",
"dep:rustc_span",
]
# tidy-alphabetical-end

View file

@ -11,11 +11,221 @@
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
// tidy-alphabetical-end
use std::fmt;
#[cfg(feature = "nightly")]
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
#[cfg(feature = "nightly")]
use rustc_span::{Symbol, sym};
pub mod visit;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(
feature = "nightly",
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
)]
pub enum IntTy {
Isize,
I8,
I16,
I32,
I64,
I128,
}
impl IntTy {
pub fn name_str(&self) -> &'static str {
match *self {
IntTy::Isize => "isize",
IntTy::I8 => "i8",
IntTy::I16 => "i16",
IntTy::I32 => "i32",
IntTy::I64 => "i64",
IntTy::I128 => "i128",
}
}
#[cfg(feature = "nightly")]
pub fn name(self) -> Symbol {
match self {
IntTy::Isize => sym::isize,
IntTy::I8 => sym::i8,
IntTy::I16 => sym::i16,
IntTy::I32 => sym::i32,
IntTy::I64 => sym::i64,
IntTy::I128 => sym::i128,
}
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
IntTy::Isize => return None,
IntTy::I8 => 8,
IntTy::I16 => 16,
IntTy::I32 => 32,
IntTy::I64 => 64,
IntTy::I128 => 128,
})
}
pub fn normalize(&self, target_width: u32) -> Self {
match self {
IntTy::Isize => match target_width {
16 => IntTy::I16,
32 => IntTy::I32,
64 => IntTy::I64,
_ => unreachable!(),
},
_ => *self,
}
}
pub fn to_unsigned(self) -> UintTy {
match self {
IntTy::Isize => UintTy::Usize,
IntTy::I8 => UintTy::U8,
IntTy::I16 => UintTy::U16,
IntTy::I32 => UintTy::U32,
IntTy::I64 => UintTy::U64,
IntTy::I128 => UintTy::U128,
}
}
}
impl fmt::Debug for IntTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name_str())
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
#[cfg_attr(
feature = "nightly",
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
)]
pub enum UintTy {
Usize,
U8,
U16,
U32,
U64,
U128,
}
impl UintTy {
pub fn name_str(&self) -> &'static str {
match *self {
UintTy::Usize => "usize",
UintTy::U8 => "u8",
UintTy::U16 => "u16",
UintTy::U32 => "u32",
UintTy::U64 => "u64",
UintTy::U128 => "u128",
}
}
#[cfg(feature = "nightly")]
pub fn name(self) -> Symbol {
match self {
UintTy::Usize => sym::usize,
UintTy::U8 => sym::u8,
UintTy::U16 => sym::u16,
UintTy::U32 => sym::u32,
UintTy::U64 => sym::u64,
UintTy::U128 => sym::u128,
}
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
UintTy::Usize => return None,
UintTy::U8 => 8,
UintTy::U16 => 16,
UintTy::U32 => 32,
UintTy::U64 => 64,
UintTy::U128 => 128,
})
}
pub fn normalize(&self, target_width: u32) -> Self {
match self {
UintTy::Usize => match target_width {
16 => UintTy::U16,
32 => UintTy::U32,
64 => UintTy::U64,
_ => unreachable!(),
},
_ => *self,
}
}
pub fn to_signed(self) -> IntTy {
match self {
UintTy::Usize => IntTy::Isize,
UintTy::U8 => IntTy::I8,
UintTy::U16 => IntTy::I16,
UintTy::U32 => IntTy::I32,
UintTy::U64 => IntTy::I64,
UintTy::U128 => IntTy::I128,
}
}
}
impl fmt::Debug for UintTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name_str())
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(
feature = "nightly",
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
)]
pub enum FloatTy {
F16,
F32,
F64,
F128,
}
impl FloatTy {
pub fn name_str(self) -> &'static str {
match self {
FloatTy::F16 => "f16",
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
FloatTy::F128 => "f128",
}
}
#[cfg(feature = "nightly")]
pub fn name(self) -> Symbol {
match self {
FloatTy::F16 => sym::f16,
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
FloatTy::F128 => sym::f128,
}
}
pub fn bit_width(self) -> u64 {
match self {
FloatTy::F16 => 16,
FloatTy::F32 => 32,
FloatTy::F64 => 64,
FloatTy::F128 => 128,
}
}
}
impl fmt::Debug for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name_str())
}
}
/// The movability of a coroutine / closure literal:
/// whether a coroutine contains self-references, causing it to be `!Unpin`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]

View file

@ -11,7 +11,6 @@ doctest = false
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -4,11 +4,11 @@ use std::sync::Arc;
use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
use rustc_ast_pretty::pprust::expr_to_string;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{HirId, find_attr};
use rustc_middle::span_bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::errors::report_lit_error;

View file

@ -311,7 +311,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
);
self.with_parent(const_arg.hir_id, |this| {
intravisit::walk_ambig_const_arg(this, const_arg);
intravisit::walk_const_arg(this, const_arg);
});
}

View file

@ -2,11 +2,11 @@ use rustc_abi::ExternAbi;
use rustc_ast::ptr::P;
use rustc_ast::visit::AssocCtxt;
use rustc_ast::*;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin};
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, find_attr};
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::span_bug;
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};

View file

@ -675,7 +675,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let bodies = SortedMap::from_presorted_elements(bodies);
// Don't hash unless necessary, because it's expensive.
let (opt_hash_including_bodies, attrs_hash, delayed_lints_hash) =
let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash, delayed_lints_hash } =
self.tcx.hash_owner_nodes(node, &bodies, &attrs, &delayed_lints, define_opaque);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);

View file

@ -1,16 +0,0 @@
[package]
name = "rustc_attr_data_structures"
version = "0.0.0"
edition = "2024"
[dependencies]
# tidy-alphabetical-start
rustc_abi = {path = "../rustc_abi"}
rustc_ast = {path = "../rustc_ast"}
rustc_ast_pretty = {path = "../rustc_ast_pretty"}
rustc_data_structures = {path = "../rustc_data_structures"}
rustc_macros = {path = "../rustc_macros"}
rustc_serialize = {path = "../rustc_serialize"}
rustc_span = {path = "../rustc_span"}
thin-vec = "0.2.12"
# tidy-alphabetical-end

View file

@ -1,16 +0,0 @@
use rustc_macros::HashStable_Generic;
use rustc_span::Span;
#[derive(Clone, Debug, HashStable_Generic)]
pub struct AttributeLint<Id> {
pub id: Id,
pub span: Span,
pub kind: AttributeLintKind,
}
#[derive(Clone, Debug, HashStable_Generic)]
pub enum AttributeLintKind {
UnusedDuplicate { this: Span, other: Span, warning: bool },
IllFormedAttributeInput { suggestions: Vec<String> },
EmptyAttribute { first_span: Span },
}

View file

@ -8,7 +8,6 @@ edition = "2024"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -1,7 +1,7 @@
use std::iter;
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use super::{CombineAttributeParser, ConvertFn};

View file

@ -1,6 +1,7 @@
use rustc_ast::{LitKind, NodeId};
use rustc_attr_data_structures::{CfgEntry, RustcVersion};
use rustc_feature::{AttributeTemplate, Features, template};
use rustc_hir::RustcVersion;
use rustc_hir::attrs::CfgEntry;
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_session::lint::BuiltinLintDiag;

View file

@ -1,7 +1,7 @@
use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::RustcVersion;
use rustc_feature::{Features, GatedCfg, find_gated_cfg};
use rustc_hir::RustcVersion;
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::{AttributeKind, CoverageAttrKind, OptimizeAttr, UsedBy};
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::{AttributeKind, CoverageAttrKind, OptimizeAttr, UsedBy};
use rustc_session::parse::feature_err;
use rustc_span::{Span, Symbol, sym};
@ -374,11 +374,3 @@ impl<S: Stage> CombineAttributeParser<S> for TargetFeatureParser {
features
}
}
pub(crate) struct OmitGdbPrettyPrinterSectionParser;
impl<S: Stage> NoArgsAttributeParser<S> for OmitGdbPrettyPrinterSectionParser {
const PATH: &[Symbol] = &[sym::omit_gdb_pretty_printer_section];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::OmitGdbPrettyPrinterSection;
}

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::template;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_span::{Span, Symbol, sym};
use super::util::parse_version;

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};

View file

@ -2,9 +2,9 @@
// note: need to model better how duplicate attr errors work when not using
// SingleAttributeParser which is what we have two of here.
use rustc_attr_data_structures::lints::AttributeLintKind;
use rustc_attr_data_structures::{AttributeKind, InlineAttr};
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::{AttributeKind, InlineAttr};
use rustc_hir::lints::AttributeLintKind;
use rustc_span::{Symbol, sym};
use super::{AcceptContext, AttributeOrder, OnDuplicate};

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::attrs::AttributeKind::{LinkName, LinkOrdinal, LinkSection};
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{

View file

@ -1,4 +1,4 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};

View file

@ -1,4 +1,4 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::{AttributeKind, MacroUseArgs};
use rustc_errors::DiagArgValue;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;

View file

@ -16,8 +16,8 @@
use std::marker::PhantomData;
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol};
use thin_vec::ThinVec;

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_errors::DiagArgValue;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};

View file

@ -1,4 +1,4 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};

View file

@ -1,4 +1,4 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;

View file

@ -1,7 +1,7 @@
use rustc_abi::Align;
use rustc_ast::{IntTy, LitIntType, LitKind, UintTy};
use rustc_attr_data_structures::{AttributeKind, IntType, ReprAttr};
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::{AttributeKind, IntType, ReprAttr};
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
use super::{AcceptMapping, AttributeParser, CombineAttributeParser, ConvertFn, FinalizeContext};

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};

View file

@ -1,4 +1,4 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};

View file

@ -1,11 +1,12 @@
use std::num::NonZero;
use rustc_attr_data_structures::{
AttributeKind, DefaultBodyStability, PartialConstStability, Stability, StabilityLevel,
StableSince, UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_errors::ErrorGuaranteed;
use rustc_feature::template;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::{
DefaultBodyStability, PartialConstStability, Stability, StabilityLevel, StableSince,
UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_span::{Ident, Span, Symbol, sym};
use super::util::parse_version;

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::lints::AttributeLintKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};

View file

@ -1,7 +1,7 @@
use core::mem;
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{

View file

@ -1,5 +1,5 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::attrs::AttributeKind;
use rustc_span::hygiene::Transparency;
use rustc_span::{Symbol, sym};

View file

@ -1,6 +1,6 @@
use rustc_ast::attr::{AttributeExt, first_attr_value_str_by_name};
use rustc_attr_data_structures::RustcVersion;
use rustc_feature::is_builtin_attr_name;
use rustc_hir::RustcVersion;
use rustc_span::{Symbol, sym};
/// Parse a rustc version number written inside string literal in an attribute,

View file

@ -5,10 +5,10 @@ use std::sync::LazyLock;
use private::Sealed;
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
use rustc_errors::{DiagCtxtHandle, Diagnostic};
use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId, HirId};
use rustc_session::Session;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
@ -17,9 +17,8 @@ use crate::attributes::allow_unstable::{
AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
};
use crate::attributes::codegen_attrs::{
ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser,
OmitGdbPrettyPrinterSectionParser, OptimizeParser, TargetFeatureParser, TrackCallerParser,
UsedParser,
ColdParser, CoverageParser, ExportNameParser, NakedParser, NoMangleParser, OptimizeParser,
TargetFeatureParser, TrackCallerParser, UsedParser,
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser;
@ -62,15 +61,23 @@ use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
use crate::parser::{ArgParser, MetaItemParser, PathParser};
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
macro_rules! group_type {
($stage: ty) => {
LazyLock<(
BTreeMap<&'static [Symbol], Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $stage>, &ArgParser<'a>) + Send + Sync>)>>,
Vec<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $stage>) -> Option<AttributeKind>>>
)>
};
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
struct GroupTypeInner<S: Stage> {
accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,
finalizers: Vec<FinalizeFn<S>>,
}
struct GroupTypeInnerAccept<S: Stage> {
template: AttributeTemplate,
accept_fn: AcceptFn<S>,
}
type AcceptFn<S> =
Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>;
type FinalizeFn<S> =
Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, S>) -> Option<AttributeKind>>;
macro_rules! attribute_parsers {
(
pub(crate) static $name: ident = [$($names: ty),* $(,)?];
@ -93,11 +100,11 @@ macro_rules! attribute_parsers {
}
};
(
@[$ty: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
@[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
) => {
pub(crate) static $name: group_type!($ty) = LazyLock::new(|| {
let mut accepts = BTreeMap::<_, Vec<(AttributeTemplate, Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, $ty>, &ArgParser<'a>) + Send + Sync>)>>::new();
let mut finalizes = Vec::<Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, $ty>) -> Option<AttributeKind>>>::new();
pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| {
let mut accepts = BTreeMap::<_, Vec<GroupTypeInnerAccept<$stage>>>::new();
let mut finalizes = Vec::<FinalizeFn<$stage>>::new();
$(
{
thread_local! {
@ -105,11 +112,14 @@ macro_rules! attribute_parsers {
};
for (path, template, accept_fn) in <$names>::ATTRIBUTES {
accepts.entry(*path).or_default().push((*template, Box::new(|cx, args| {
STATE_OBJECT.with_borrow_mut(|s| {
accept_fn(s, cx, args)
accepts.entry(*path).or_default().push(GroupTypeInnerAccept {
template: *template,
accept_fn: Box::new(|cx, args| {
STATE_OBJECT.with_borrow_mut(|s| {
accept_fn(s, cx, args)
})
})
})));
});
}
finalizes.push(Box::new(|cx| {
@ -119,7 +129,7 @@ macro_rules! attribute_parsers {
}
)*
(accepts, finalizes)
GroupTypeInner { accepters:accepts, finalizers:finalizes }
});
};
}
@ -187,7 +197,6 @@ attribute_parsers!(
Single<WithoutArgs<NoImplicitPreludeParser>>,
Single<WithoutArgs<NoMangleParser>>,
Single<WithoutArgs<NonExhaustiveParser>>,
Single<WithoutArgs<OmitGdbPrettyPrinterSectionParser>>,
Single<WithoutArgs<ParenSugarParser>>,
Single<WithoutArgs<PassByValueParser>>,
Single<WithoutArgs<PointeeParser>>,
@ -215,7 +224,7 @@ pub trait Stage: Sized + 'static + Sealed {
type Id: Copy;
const SHOULD_EMIT_LINTS: bool;
fn parsers() -> &'static group_type!(Self);
fn parsers() -> &'static GroupType<Self>;
fn emit_err<'sess>(
&self,
@ -230,7 +239,7 @@ impl Stage for Early {
type Id = NodeId;
const SHOULD_EMIT_LINTS: bool = false;
fn parsers() -> &'static group_type!(Self) {
fn parsers() -> &'static GroupType<Self> {
&early::ATTRIBUTE_PARSERS
}
fn emit_err<'sess>(
@ -252,7 +261,7 @@ impl Stage for Late {
type Id = HirId;
const SHOULD_EMIT_LINTS: bool = true;
fn parsers() -> &'static group_type!(Self) {
fn parsers() -> &'static GroupType<Self> {
&late::ATTRIBUTE_PARSERS
}
fn emit_err<'sess>(
@ -811,8 +820,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
let args = parser.args();
let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
if let Some(accepts) = S::parsers().0.get(parts.as_slice()) {
for (template, accept) in accepts {
if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) {
for accept in accepts {
let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
shared: SharedContext {
cx: self,
@ -821,11 +830,11 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
emit_lint: &mut emit_lint,
},
attr_span: lower_span(attr.span),
template,
template: &accept.template,
attr_path: path.get_attribute_path(),
};
accept(&mut cx, args)
(accept.accept_fn)(&mut cx, args)
}
} else {
// If we're here, we must be compiling a tool attribute... Or someone
@ -856,7 +865,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
}
let mut parsed_attributes = Vec::new();
for f in &S::parsers().1 {
for f in &S::parsers().finalizers {
if let Some(attr) = f(&mut FinalizeContext {
shared: SharedContext {
cx: self,
@ -877,7 +886,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
/// Returns whether there is a parser for an attribute with this name
pub fn is_parsed_attribute(path: &[Symbol]) -> bool {
Late::parsers().0.contains_key(path)
Late::parsers().accepters.contains_key(path)
}
fn lower_attr_args(&self, args: &ast::AttrArgs, lower_span: impl Fn(Span) -> Span) -> AttrArgs {

View file

@ -1,13 +1,13 @@
//! Centralized logic for parsing and attributes.
//!
//! ## Architecture
//! This crate is part of a series of crates that handle attribute processing.
//! - [rustc_attr_data_structures](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_data_structures/index.html): Defines the data structures that store parsed attributes
//! This crate is part of a series of crates and modules that handle attribute processing.
//! - [rustc_hir::attrs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html): Defines the data structures that store parsed attributes
//! - [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html): This crate, handles the parsing of attributes
//! - (planned) rustc_attr_validation: Will handle attribute validation
//! - (planned) rustc_attr_validation: Will handle attribute validation, logic currently handled in `rustc_passes`
//!
//! The separation between data structures and parsing follows the principle of separation of concerns.
//! Data structures (`rustc_attr_data_structures`) define what attributes look like after parsing.
//! Data structures (`rustc_hir::attrs`) define what attributes look like after parsing.
//! This crate (`rustc_attr_parsing`) handles how to convert raw tokens into those structures.
//! This split allows other parts of the compiler to use the data structures without needing
//! the parsing logic, making the codebase more modular and maintainable.
@ -62,7 +62,7 @@
//! a "stability" of an item. So, the stability attribute has an
//! [`AttributeParser`](attributes::AttributeParser) that recognizes both the `#[stable()]`
//! and `#[unstable()]` syntactic attributes, and at the end produce a single
//! [`AttributeKind::Stability`](rustc_attr_data_structures::AttributeKind::Stability).
//! [`AttributeKind::Stability`](rustc_hir::attrs::AttributeKind::Stability).
//!
//! When multiple instances of the same attribute are allowed, they're combined into a single
//! semantic attribute. For example:

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::lints::{AttributeLint, AttributeLintKind};
use rustc_errors::{DiagArgValue, LintEmitter};
use rustc_hir::HirId;
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use crate::session_diagnostics;

View file

@ -3,7 +3,7 @@ use std::rc::Rc;
use rustc_errors::Diag;
use rustc_hir::def_id::LocalDefId;
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc_infer::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};
use rustc_infer::infer::{
InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt as _,
};
@ -277,7 +277,7 @@ where
// `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below:
// the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
// test. Check after #85499 lands to see if its fixes have erased this difference.
let (param_env, value) = key.into_parts();
let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.normalize(&cause, param_env, value.value);
let diag = try_extract_error_from_fulfill_cx(
@ -324,7 +324,7 @@ where
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
let (param_env, value) = key.into_parts();
let ty::ParamEnvAnd { param_env, value } = key;
let _ = ocx.deeply_normalize(&cause, param_env, value.value);
let diag = try_extract_error_from_fulfill_cx(
@ -454,25 +454,24 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>(
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
_ => a_region == b_region,
};
let mut check =
|constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match *constraint {
Constraint::RegSubReg(sub, sup)
if ((exact && sup == placeholder_region)
|| (!exact && regions_the_same(sup, placeholder_region)))
&& sup != sub =>
{
Some((sub, cause.clone()))
}
Constraint::VarSubReg(vid, sup)
if (exact
&& sup == placeholder_region
&& !universe_of_region(vid).can_name(placeholder_universe))
|| (!exact && regions_the_same(sup, placeholder_region)) =>
{
Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
}
_ => None,
};
let mut check = |c: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match c.kind {
ConstraintKind::RegSubReg
if ((exact && c.sup == placeholder_region)
|| (!exact && regions_the_same(c.sup, placeholder_region)))
&& c.sup != c.sub =>
{
Some((c.sub, cause.clone()))
}
ConstraintKind::VarSubReg
if (exact
&& c.sup == placeholder_region
&& !universe_of_region(c.sub.as_var()).can_name(placeholder_universe))
|| (!exact && regions_the_same(c.sup, placeholder_region)) =>
{
Some((c.sub, cause.clone()))
}
_ => None,
};
let mut find_culprit = |exact_match: bool| {
region_constraints

View file

@ -417,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// minimum values.
///
/// For example:
/// ```
/// ```ignore (illustrative)
/// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
/// ```
/// would initialize two variables like so:

View file

@ -86,7 +86,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// them with fresh ty vars.
resume_ty: next_ty_var(),
yield_ty: next_ty_var(),
witness: next_ty_var(),
},
)
.args,

View file

@ -187,7 +187,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
types: &mut |_bound_ty: ty::BoundTy| {
unreachable!("we only replace regions in nll_relate, not types")
},
consts: &mut |_bound_var: ty::BoundVar| {
consts: &mut |_bound_const: ty::BoundConst| {
unreachable!("we only replace regions in nll_relate, not consts")
},
};
@ -226,7 +226,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
types: &mut |_bound_ty: ty::BoundTy| {
unreachable!("we only replace regions in nll_relate, not types")
},
consts: &mut |_bound_var: ty::BoundVar| {
consts: &mut |_bound_const: ty::BoundConst| {
unreachable!("we only replace regions in nll_relate, not consts")
},
};

View file

@ -10,7 +10,6 @@ doctest = false
# tidy-alphabetical-start
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -187,10 +187,10 @@ use rustc_ast::{
self as ast, AnonConst, AttrArgs, BindingMode, ByRef, DelimArgs, EnumDef, Expr, GenericArg,
GenericParamKind, Generics, Mutability, PatKind, Safety, VariantData,
};
use rustc_attr_data_structures::{AttributeKind, ReprPacked};
use rustc_attr_parsing::AttributeParser;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_hir::Attribute;
use rustc_hir::attrs::{AttributeKind, ReprPacked};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
use thin_vec::{ThinVec, thin_vec};
use ty::{Bounds, Path, Ref, Self_, Ty};

View file

@ -4,12 +4,12 @@ use rustc_ast::ptr::P;
use rustc_ast::visit::{self, Visitor};
use rustc_ast::{self as ast, HasNodeId, NodeId, attr};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_parsing::AttributeParser;
use rustc_errors::DiagCtxtHandle;
use rustc_expand::base::{ExtCtxt, ResolverExpand};
use rustc_expand::expand::{AstFragment, ExpansionConfig};
use rustc_feature::Features;
use rustc_hir::attrs::AttributeKind;
use rustc_session::Session;
use rustc_span::hygiene::AstPass;
use rustc_span::source_map::SourceMap;

View file

@ -4,3 +4,5 @@ codegen_gcc_unwinding_inline_asm =
codegen_gcc_copy_bitcode = failed to copy bitcode to object file: {$err}
codegen_gcc_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$gcc_err})
codegen_gcc_explicit_tail_calls_unsupported = explicit tail calls with the 'become' keyword are not implemented in the GCC backend

View file

@ -2,8 +2,8 @@
use gccjit::FnAttribute;
use gccjit::Function;
#[cfg(feature = "master")]
use rustc_attr_data_structures::InlineAttr;
use rustc_attr_data_structures::InstructionSetAttr;
use rustc_hir::attrs::InlineAttr;
use rustc_hir::attrs::InstructionSetAttr;
#[cfg(feature = "master")]
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
#[cfg(feature = "master")]

View file

@ -34,6 +34,7 @@ use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
use crate::common::{SignType, TypeReflection, type_is_pointer};
use crate::context::CodegenCx;
use crate::errors;
use crate::intrinsic::llvm;
use crate::type_of::LayoutGccExt;
@ -1742,6 +1743,20 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
call
}
fn tail_call(
&mut self,
_llty: Self::Type,
_fn_attrs: Option<&CodegenFnAttrs>,
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
_llfn: Self::Value,
_args: &[Self::Value],
_funclet: Option<&Self::Funclet>,
_instance: Option<Instance<'tcx>>,
) {
// FIXME: implement support for explicit tail calls like rustc_codegen_llvm.
self.tcx.dcx().emit_fatal(errors::ExplicitTailCallsUnsupported);
}
fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
// FIXME(antoyo): this does not zero-extend.
self.gcc_int_cast(value, dest_typ)

View file

@ -106,7 +106,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
// This is a monomorphization of a generic function.
if !(cx.tcx.sess.opts.share_generics()
|| tcx.codegen_instance_attrs(instance.def).inline
== rustc_attr_data_structures::InlineAttr::Never)
== rustc_hir::attrs::InlineAttr::Never)
{
// When not sharing generics, all instances are in the same
// crate and have hidden visibility.

View file

@ -19,3 +19,7 @@ pub(crate) struct CopyBitcode {
pub(crate) struct LtoBitcodeFromRlib {
pub gcc_err: String,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc_explicit_tail_calls_unsupported)]
pub(crate) struct ExplicitTailCallsUnsupported;

View file

@ -35,7 +35,6 @@ extern crate tracing;
extern crate rustc_abi;
extern crate rustc_apfloat;
extern crate rustc_ast;
extern crate rustc_attr_data_structures;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;

View file

@ -19,7 +19,6 @@ object = { version = "0.37.0", default-features = false, features = ["std", "rea
rustc-demangle = "0.1.21"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
@ -38,11 +37,14 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_target = { path = "../rustc_target" }
serde = { version = "1", features = [ "derive" ]}
serde = { version = "1", features = ["derive"] }
serde_json = "1"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
# tidy-alphabetical-end
[features]
# tidy-alphabetical-start
check_only = ["rustc_llvm/check_only"]
# tidy-alphabetical-end

View file

@ -1,6 +1,6 @@
//! Set and unset common attributes on LLVM values.
use rustc_attr_data_structures::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_codegen_ssa::traits::*;
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};
use rustc_middle::ty::{self, TyCtxt};

View file

@ -15,6 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
@ -24,7 +25,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_sanitizers::{cfi, kcfi};
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
use rustc_target::callconv::{FnAbi, PassMode};
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
use smallvec::SmallVec;
use tracing::{debug, instrument};
@ -1431,6 +1432,28 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
call
}
fn tail_call(
&mut self,
llty: Self::Type,
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
llfn: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
instance: Option<Instance<'tcx>>,
) {
let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance);
llvm::LLVMRustSetTailCallKind(call, llvm::TailCallKind::MustTail);
match &fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
mode @ PassMode::Cast { .. } => {
bug!("Encountered `PassMode::{mode:?}` during codegen")
}
}
}
fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
}

View file

@ -103,7 +103,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
// This is a monomorphization of a generic function.
if !(cx.tcx.sess.opts.share_generics()
|| tcx.codegen_instance_attrs(instance.def).inline
== rustc_attr_data_structures::InlineAttr::Never)
== rustc_hir::attrs::InlineAttr::Never)
{
// When not sharing generics, all instances are in the same
// crate and have hidden visibility.

View file

@ -39,7 +39,10 @@ impl Coords {
/// or other expansions), and if it does happen then skipping a span or function is
/// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span) -> Option<Coords> {
let span = ensure_non_empty_span(source_map, span)?;
if span.is_empty() {
debug_assert!(false, "can't make coords from empty span: {span:?}");
return None;
}
let lo = span.lo();
let hi = span.hi();
@ -70,29 +73,6 @@ pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span)
})
}
fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> {
if !span.is_empty() {
return Some(span);
}
// The span is empty, so try to enlarge it to cover an adjacent '{' or '}'.
source_map
.span_to_source(span, |src, start, end| try {
// Adjusting span endpoints by `BytePos(1)` is normally a bug,
// but in this case we have specifically checked that the character
// we're skipping over is one of two specific ASCII characters, so
// adjusting by exactly 1 byte is correct.
if src.as_bytes().get(end).copied() == Some(b'{') {
Some(span.with_hi(span.hi() + BytePos(1)))
} else if start > 0 && src.as_bytes()[start - 1] == b'}' {
Some(span.with_lo(span.lo() - BytePos(1)))
} else {
None
}
})
.ok()?
}
/// If `llvm-cov` sees a source region that is improperly ordered (end < start),
/// it will immediately exit with a fatal error. To prevent that from happening,
/// discard regions that are improperly ordered, or might be interpreted in a

View file

@ -1,6 +1,5 @@
// .debug_gdb_scripts binary section.
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive;
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::LOCAL_CRATE;
@ -85,9 +84,6 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
}
pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
let omit_gdb_pretty_printer_section =
find_attr!(cx.tcx.hir_krate_attrs(), AttributeKind::OmitGdbPrettyPrinterSection);
// To ensure the section `__rustc_debug_gdb_scripts_section__` will not create
// ODR violations at link time, this section will not be emitted for rlibs since
// each rlib could produce a different set of visualizers that would be embedded
@ -116,8 +112,7 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool {
}
});
!omit_gdb_pretty_printer_section
&& cx.sess().opts.debuginfo != DebugInfo::None
cx.sess().opts.debuginfo != DebugInfo::None
&& cx.sess().target.emit_debug_gdb_scripts
&& embed_visualizers
}

View file

@ -97,6 +97,16 @@ pub(crate) enum ModuleFlagMergeBehavior {
// Consts for the LLVM CallConv type, pre-cast to usize.
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
#[allow(dead_code)]
pub(crate) enum TailCallKind {
None = 0,
Tail = 1,
MustTail = 2,
NoTail = 3,
}
/// LLVM CallingConv::ID. Should we wrap this?
///
/// See <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/CallingConv.h>
@ -1186,6 +1196,7 @@ unsafe extern "C" {
pub(crate) safe fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
pub(crate) safe fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
pub(crate) safe fn LLVMRustSetTailCallKind(CallInst: &Value, Kind: TailCallKind);
// Operations on attributes
pub(crate) fn LLVMCreateStringAttribute(

View file

@ -17,7 +17,6 @@ regex = "1.4"
rustc_abi = { path = "../rustc_abi" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -1011,11 +1011,12 @@ fn link_natively(
(Strip::Debuginfo, _) => {
strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-debug"])
}
// Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
// Per the manpage, --discard-all is the maximum safe strip level for dynamic libraries. (#93988)
(
Strip::Symbols,
CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib,
) => strip_with_external_utility(sess, stripcmd, out_filename, &["-x"]),
) => strip_with_external_utility(sess, stripcmd, out_filename, &["--discard-all"]),
(Strip::Symbols, _) => {
strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-all"])
}

View file

@ -384,7 +384,7 @@ fn exported_generic_symbols_provider_local<'tcx>(
if !tcx.sess.opts.share_generics() {
if tcx.codegen_fn_attrs(mono_item.def_id()).inline
== rustc_attr_data_structures::InlineAttr::Never
== rustc_hir::attrs::InlineAttr::Never
{
// this is OK, we explicitly allow sharing inline(never) across crates even
// without share-generics.

View file

@ -214,7 +214,9 @@ impl ModuleConfig {
false
),
emit_obj,
emit_thin_lto: sess.opts.unstable_opts.emit_thin_lto,
// thin lto summaries prevent fat lto, so do not emit them if fat
// lto is requested. See PR #136840 for background information.
emit_thin_lto: sess.opts.unstable_opts.emit_thin_lto && sess.lto() != Lto::Fat,
emit_thin_lto_summary: if_regular!(
sess.opts.output_types.contains_key(&OutputType::ThinLinkBitcode),
false

View file

@ -7,11 +7,11 @@ use itertools::Itertools;
use rustc_abi::FIRST_VARIANT;
use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr_data_structures::OptimizeAttr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
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::attrs::OptimizeAttr;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ItemId, Target};

View file

@ -3,13 +3,11 @@ use std::str::FromStr;
use rustc_abi::{Align, ExternAbi};
use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode};
use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr};
use rustc_attr_data_structures::{
AttributeKind, InlineAttr, InstructionSetAttr, UsedBy, find_attr,
};
use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, UsedBy};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
use rustc_hir::{self as hir, Attribute, LangItem, lang_items};
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
use rustc_middle::middle::codegen_fn_attrs::{
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
};
@ -527,14 +525,14 @@ fn handle_lang_items(
attrs: &[Attribute],
codegen_fn_attrs: &mut CodegenFnAttrs,
) {
let lang_item = lang_items::extract(attrs).and_then(|(name, _)| LangItem::from_name(name));
// Weak lang items have the same semantics as "std internal" symbols in the
// sense that they're preserved through all our LTO passes and only
// strippable by the linker.
//
// Additionally weak lang items have predetermined symbol names.
if let Some((name, _)) = lang_items::extract(attrs)
&& let Some(lang_item) = LangItem::from_name(name)
{
if let Some(lang_item) = lang_item {
if WEAK_LANG_ITEMS.contains(&lang_item) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
}
@ -548,8 +546,6 @@ fn handle_lang_items(
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
&& codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
{
let lang_item =
lang_items::extract(attrs).map_or(None, |(name, _span)| LangItem::from_name(name));
let mut err = tcx
.dcx()
.struct_span_err(

View file

@ -35,6 +35,14 @@ enum MergingSucc {
True,
}
/// Indicates to the call terminator codegen whether a cal
/// is a normal call or an explicit tail call.
#[derive(Debug, PartialEq)]
enum CallKind {
Normal,
Tail,
}
/// Used by `FunctionCx::codegen_terminator` for emitting common patterns
/// e.g., creating a basic block, calling a function, etc.
struct TerminatorCodegenHelper<'tcx> {
@ -160,6 +168,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
mut unwind: mir::UnwindAction,
lifetime_ends_after_call: &[(Bx::Value, Size)],
instance: Option<Instance<'tcx>>,
kind: CallKind,
mergeable_succ: bool,
) -> MergingSucc {
let tcx = bx.tcx();
@ -221,6 +230,11 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
}
};
if kind == CallKind::Tail {
bx.tail_call(fn_ty, fn_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance);
return MergingSucc::False;
}
if let Some(unwind_block) = unwind_block {
let ret_llbb = if let Some((_, target)) = destination {
fx.llbb(target)
@ -659,6 +673,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
unwind,
&[],
Some(drop_instance),
CallKind::Normal,
!maybe_null && mergeable_succ,
)
}
@ -747,8 +762,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (fn_abi, llfn, instance) = common::build_langcall(bx, span, lang_item);
// Codegen the actual panic invoke/call.
let merging_succ =
helper.do_call(self, bx, fn_abi, llfn, &args, None, unwind, &[], Some(instance), false);
let merging_succ = helper.do_call(
self,
bx,
fn_abi,
llfn,
&args,
None,
unwind,
&[],
Some(instance),
CallKind::Normal,
false,
);
assert_eq!(merging_succ, MergingSucc::False);
MergingSucc::False
}
@ -777,6 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::UnwindAction::Unreachable,
&[],
Some(instance),
CallKind::Normal,
false,
);
assert_eq!(merging_succ, MergingSucc::False);
@ -845,6 +872,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
unwind,
&[],
Some(instance),
CallKind::Normal,
mergeable_succ,
))
}
@ -860,6 +888,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
target: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
fn_span: Span,
kind: CallKind,
mergeable_succ: bool,
) -> MergingSucc {
let source_info = mir::SourceInfo { span: fn_span, ..terminator.source_info };
@ -1003,8 +1032,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// We still need to call `make_return_dest` even if there's no `target`, since
// `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited,
// and `make_return_dest` adds the return-place indirect pointer to `llargs`.
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs);
let destination = target.map(|target| (return_dest, target));
let destination = match kind {
CallKind::Normal => {
let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs);
target.map(|target| (return_dest, target))
}
CallKind::Tail => None,
};
// Split the rust-call tupled arguments off.
let (first_args, untuple) = if sig.abi() == ExternAbi::RustCall
@ -1020,6 +1054,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// to generate `lifetime_end` when the call returns.
let mut lifetime_ends_after_call: Vec<(Bx::Value, Size)> = Vec::new();
'make_args: for (i, arg) in first_args.iter().enumerate() {
if kind == CallKind::Tail && matches!(fn_abi.args[i].mode, PassMode::Indirect { .. }) {
// FIXME: https://github.com/rust-lang/rust/pull/144232#discussion_r2218543841
span_bug!(
fn_span,
"arguments using PassMode::Indirect are currently not supported for tail calls"
);
}
let mut op = self.codegen_operand(bx, &arg.node);
if let (0, Some(ty::InstanceKind::Virtual(_, idx))) = (i, instance.map(|i| i.def)) {
@ -1147,6 +1189,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
unwind,
&lifetime_ends_after_call,
instance,
kind,
mergeable_succ,
)
}
@ -1388,15 +1431,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
target,
unwind,
fn_span,
CallKind::Normal,
mergeable_succ(),
),
mir::TerminatorKind::TailCall { .. } => {
// FIXME(explicit_tail_calls): implement tail calls in ssa backend
span_bug!(
terminator.source_info.span,
"`TailCall` terminator is not yet supported by `rustc_codegen_ssa`"
)
}
mir::TerminatorKind::TailCall { ref func, ref args, fn_span } => self
.codegen_call_terminator(
helper,
bx,
terminator,
func,
args,
mir::Place::from(mir::RETURN_PLACE),
None,
mir::UnwindAction::Unreachable,
fn_span,
CallKind::Tail,
mergeable_succ(),
),
mir::TerminatorKind::CoroutineDrop | mir::TerminatorKind::Yield { .. } => {
bug!("coroutine ops in codegen")
}

View file

@ -1,5 +1,5 @@
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind};
use rustc_attr_data_structures::InstructionSetAttr;
use rustc_hir::attrs::InstructionSetAttr;
use rustc_middle::mir::mono::{Linkage, MonoItemData, Visibility};
use rustc_middle::mir::{InlineAsmOperand, START_BLOCK};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};

View file

@ -1,6 +1,6 @@
use rustc_attr_data_structures::InstructionSetAttr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::attrs::InstructionSetAttr;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;

View file

@ -595,6 +595,18 @@ pub trait BuilderMethods<'a, 'tcx>:
funclet: Option<&Self::Funclet>,
instance: Option<Instance<'tcx>>,
) -> Self::Value;
fn tail_call(
&mut self,
llty: Self::Type,
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
llfn: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
instance: Option<Instance<'tcx>>,
);
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);

View file

@ -9,7 +9,6 @@ either = "1"
rustc_abi = { path = "../rustc_abi" }
rustc_apfloat = "0.2.0"
rustc_ast = { path = "../rustc_ast" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -6,7 +6,6 @@ use std::mem;
use std::num::NonZero;
use std::ops::Deref;
use rustc_attr_data_structures as attrs;
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
@ -466,7 +465,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
/// Check the const stability of the given item (fn or trait).
fn check_callee_stability(&mut self, def_id: DefId) {
match self.tcx.lookup_const_stability(def_id) {
Some(attrs::ConstStability { level: attrs::StabilityLevel::Stable { .. }, .. }) => {
Some(hir::ConstStability { level: hir::StabilityLevel::Stable { .. }, .. }) => {
// All good.
}
None => {
@ -482,8 +481,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
});
}
}
Some(attrs::ConstStability {
level: attrs::StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
Some(hir::ConstStability {
level: hir::StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
feature,
..
}) => {
@ -891,8 +890,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
});
}
}
Some(attrs::ConstStability {
level: attrs::StabilityLevel::Unstable { .. },
Some(hir::ConstStability {
level: hir::StabilityLevel::Unstable { .. },
feature,
..
}) => {
@ -902,8 +901,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
const_stable_indirect: is_const_stable,
});
}
Some(attrs::ConstStability {
level: attrs::StabilityLevel::Stable { .. },
Some(hir::ConstStability {
level: hir::StabilityLevel::Stable { .. },
..
}) => {
// All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it

View file

@ -5,11 +5,12 @@
//! it finds operations that are invalid in a certain context.
use rustc_errors::DiagCtxtHandle;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, find_attr};
use rustc_middle::ty::{self, PolyFnSig, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::Symbol;
use {rustc_attr_data_structures as attrs, rustc_hir as hir};
pub use self::qualifs::Qualif;
@ -82,7 +83,7 @@ pub fn rustc_allow_const_fn_unstable(
) -> bool {
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
attrs::find_attr!(attrs, attrs::AttributeKind::AllowConstFnUnstable(syms, _) if syms.contains(&feature_gate))
find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms, _) if syms.contains(&feature_gate))
}
/// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable".

View file

@ -11,6 +11,7 @@ use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::sym;
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
use tracing::field::Empty;
use tracing::{info, instrument, trace};
use super::{
@ -18,7 +19,8 @@ use super::{
Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok,
throw_ub, throw_ub_custom, throw_unsup_format,
};
use crate::fluent_generated as fluent;
use crate::interpret::EnteredTraceSpan;
use crate::{enter_trace_span, fluent_generated as fluent};
/// An argument passed to a function.
#[derive(Clone, Debug)]
@ -344,6 +346,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
destination: &PlaceTy<'tcx, M::Provenance>,
mut cont: ReturnContinuation,
) -> InterpResult<'tcx> {
let _span = enter_trace_span!(M, step::init_stack_frame, %instance, tracing_separate_thread = Empty);
// Compute callee information.
// FIXME: for variadic support, do we have to somehow determine callee's extra_args?
let callee_fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
@ -523,7 +527,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
target: Option<mir::BasicBlock>,
unwind: mir::UnwindAction,
) -> InterpResult<'tcx> {
trace!("init_fn_call: {:#?}", fn_val);
let _span =
enter_trace_span!(M, step::init_fn_call, tracing_separate_thread = Empty, ?fn_val)
.or_if_tracing_disabled(|| trace!("init_fn_call: {:#?}", fn_val));
let instance = match fn_val {
FnVal::Instance(instance) => instance,

View file

@ -113,7 +113,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// See [LayoutOf::layout_of] for the original documentation.
#[inline(always)]
pub fn layout_of(&self, ty: Ty<'tcx>) -> <Self as LayoutOfHelpers<'tcx>>::LayoutOfResult {
let _span = enter_trace_span!(M, "InterpCx::layout_of", ty = ?ty.kind());
let _span = enter_trace_span!(M, layouting::layout_of, ty = ?ty.kind());
LayoutOf::layout_of(self, ty)
}
@ -126,7 +126,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
sig: ty::PolyFnSig<'tcx>,
extra_args: &'tcx ty::List<Ty<'tcx>>,
) -> <Self as FnAbiOfHelpers<'tcx>>::FnAbiOfResult {
let _span = enter_trace_span!(M, "InterpCx::fn_abi_of_fn_ptr", ?sig, ?extra_args);
let _span = enter_trace_span!(M, layouting::fn_abi_of_fn_ptr, ?sig, ?extra_args);
FnAbiOf::fn_abi_of_fn_ptr(self, sig, extra_args)
}
@ -139,7 +139,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
instance: ty::Instance<'tcx>,
extra_args: &'tcx ty::List<Ty<'tcx>>,
) -> <Self as FnAbiOfHelpers<'tcx>>::FnAbiOfResult {
let _span = enter_trace_span!(M, "InterpCx::fn_abi_of_instance", ?instance, ?extra_args);
let _span = enter_trace_span!(M, layouting::fn_abi_of_instance, ?instance, ?extra_args);
FnAbiOf::fn_abi_of_instance(self, instance, extra_args)
}
}

View file

@ -13,6 +13,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
use rustc_middle::{bug, mir, span_bug, ty};
use rustc_span::DUMMY_SP;
use tracing::field::Empty;
use tracing::trace;
use super::{
@ -20,6 +21,7 @@ use super::{
OffsetMode, PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub,
from_known_layout, interp_ok, mir_assign_valid_types, throw_ub,
};
use crate::enter_trace_span;
/// An `Immediate` represents a single immediate self-contained Rust value.
///
@ -770,6 +772,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
mir_place: mir::Place<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
let _span = enter_trace_span!(
M,
step::eval_place_to_op,
?mir_place,
tracing_separate_thread = Empty
);
// Do not use the layout passed in as argument if the base we are looking at
// here is not the entire place.
let layout = if mir_place.projection.is_empty() { layout } else { None };
@ -813,6 +822,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
mir_op: &mir::Operand<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
let _span =
enter_trace_span!(M, step::eval_operand, ?mir_op, tracing_separate_thread = Empty);
use rustc_middle::mir::Operand::*;
let op = match mir_op {
// FIXME: do some more logic on `move` to invalidate the old location

View file

@ -9,6 +9,7 @@ use rustc_abi::{BackendRepr, HasDataLayout, Size};
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{bug, mir, span_bug};
use tracing::field::Empty;
use tracing::{instrument, trace};
use super::{
@ -16,6 +17,7 @@ use super::{
InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer,
Projectable, Provenance, Scalar, alloc_range, interp_ok, mir_assign_valid_types,
};
use crate::enter_trace_span;
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
/// Information required for the sound usage of a `MemPlace`.
@ -524,6 +526,9 @@ where
&self,
mir_place: mir::Place<'tcx>,
) -> InterpResult<'tcx, PlaceTy<'tcx, M::Provenance>> {
let _span =
enter_trace_span!(M, step::eval_place, ?mir_place, tracing_separate_thread = Empty);
let mut place = self.local_to_place(mir_place.local)?;
// Using `try_fold` turned out to be bad for performance, hence the loop.
for elem in mir_place.projection.iter() {

View file

@ -397,11 +397,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Finish things up.
M::after_stack_push(self)?;
self.frame_mut().loc = Left(mir::Location::START);
// `tracing_separate_thread` is used to instruct the chrome_tracing [tracing::Layer] in Miri
// `tracing_separate_thread` is used to instruct the tracing_chrome [tracing::Layer] in Miri
// to put the "frame" span on a separate trace thread/line than other spans, to make the
// visualization in https://ui.perfetto.dev easier to interpret. It is set to a value of
// visualization in <https://ui.perfetto.dev> easier to interpret. It is set to a value of
// [tracing::field::Empty] so that other tracing layers (e.g. the logger) will ignore it.
let span = info_span!("frame", tracing_separate_thread = Empty, "{}", instance);
let span = info_span!("frame", tracing_separate_thread = Empty, frame = %instance);
self.frame_mut().tracing_span.enter(span);
interp_ok(())

View file

@ -9,13 +9,15 @@ use rustc_middle::ty::{self, Instance, Ty};
use rustc_middle::{bug, mir, span_bug};
use rustc_span::source_map::Spanned;
use rustc_target::callconv::FnAbi;
use tracing::field::Empty;
use tracing::{info, instrument, trace};
use super::{
FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format,
};
use crate::util;
use crate::interpret::EnteredTraceSpan;
use crate::{enter_trace_span, util};
struct EvaluatedCalleeAndArgs<'tcx, M: Machine<'tcx>> {
callee: FnVal<'tcx, M::ExtraFnVal>,
@ -74,7 +76,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
///
/// This does NOT move the statement counter forward, the caller has to do that!
pub fn eval_statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
info!("{:?}", stmt);
let _span = enter_trace_span!(
M,
step::eval_statement,
stmt = ?stmt.kind,
span = ?stmt.source_info.span,
tracing_separate_thread = Empty,
)
.or_if_tracing_disabled(|| info!(stmt = ?stmt.kind));
use rustc_middle::mir::StatementKind::*;
@ -456,7 +465,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tcx> {
info!("{:?}", terminator.kind);
let _span = enter_trace_span!(
M,
step::eval_terminator,
terminator = ?terminator.kind,
span = ?terminator.source_info.span,
tracing_separate_thread = Empty,
)
.or_if_tracing_disabled(|| info!(terminator = ?terminator.kind));
use rustc_middle::mir::TerminatorKind::*;
match terminator.kind {

View file

@ -48,18 +48,104 @@ pub(crate) fn create_static_alloc<'tcx>(
/// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a
/// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when
/// tracing is disabled.
pub trait EnteredTraceSpan {}
impl EnteredTraceSpan for () {}
impl EnteredTraceSpan for tracing::span::EnteredSpan {}
/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span].
/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the
/// default implementation (i.e. when it does not actually enter the span but instead returns `()`).
/// Note: the result of this macro **must be used** because the span is exited when it's dropped.
#[macro_export]
macro_rules! enter_trace_span {
($machine:ident, $($tt:tt)*) => {
$machine::enter_trace_span(|| tracing::info_span!($($tt)*))
/// tracing is disabled. Also see [crate::enter_trace_span!] below.
pub trait EnteredTraceSpan {
/// Allows executing an alternative function when tracing is disabled. Useful for example if you
/// want to open a trace span when tracing is enabled, and alternatively just log a line when
/// tracing is disabled.
fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self;
}
impl EnteredTraceSpan for () {
fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self {
f(); // tracing is disabled, execute the function
self
}
}
impl EnteredTraceSpan for tracing::span::EnteredSpan {
fn or_if_tracing_disabled(self, _f: impl FnOnce()) -> Self {
self // tracing is enabled, don't execute anything
}
}
/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span!].
/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the
/// default implementation (i.e. when it does not actually enter the span but instead returns `()`).
/// This macro takes a type implementing the [crate::interpret::Machine] trait as its first argument
/// and otherwise accepts the same syntax as [tracing::span!] (see some tips below).
/// Note: the result of this macro **must be used** because the span is exited when it's dropped.
///
/// ### Syntax accepted by this macro
///
/// The full documentation for the [tracing::span!] syntax can be found at [tracing] under "Using the
/// Macros". A few possibly confusing syntaxes are listed here:
/// ```rust
/// # use rustc_const_eval::enter_trace_span;
/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
/// # let my_display_var = String::new();
/// # let my_debug_var = String::new();
/// // logs a span named "hello" with a field named "arg" of value 42 (works only because
/// // 42 implements the tracing::Value trait, otherwise use one of the options below)
/// let _span = enter_trace_span!(M, "hello", arg = 42);
/// // logs a field called "my_display_var" using the Display implementation
/// let _span = enter_trace_span!(M, "hello", %my_display_var);
/// // logs a field called "my_debug_var" using the Debug implementation
/// let _span = enter_trace_span!(M, "hello", ?my_debug_var);
/// ```
///
/// ### `NAME::SUBNAME` syntax
///
/// In addition to the syntax accepted by [tracing::span!], this macro optionally allows passing
/// the span name (i.e. the first macro argument) in the form `NAME::SUBNAME` (without quotes) to
/// indicate that the span has name "NAME" (usually the name of the component) and has an additional
/// more specific name "SUBNAME" (usually the function name). The latter is passed to the [tracing]
/// infrastructure as a span field with the name "NAME". This allows not being distracted by
/// subnames when looking at the trace in <https://ui.perfetto.dev>, but when deeper introspection
/// is needed within a component, it's still possible to view the subnames directly in the UI by
/// selecting a span, clicking on the "NAME" argument on the right, and clicking on "Visualize
/// argument values".
/// ```rust
/// # use rustc_const_eval::enter_trace_span;
/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
/// // for example, the first will expand to the second
/// let _span = enter_trace_span!(M, borrow_tracker::on_stack_pop, /* ... */);
/// let _span = enter_trace_span!(M, "borrow_tracker", borrow_tracker = "on_stack_pop", /* ... */);
/// ```
///
/// ### `tracing_separate_thread` parameter
///
/// This macro was introduced to obtain better traces of Miri without impacting release performance.
/// Miri saves traces using the the `tracing_chrome` `tracing::Layer` so that they can be visualized
/// in <https://ui.perfetto.dev>. To instruct `tracing_chrome` to put some spans on a separate trace
/// thread/line than other spans when viewed in <https://ui.perfetto.dev>, you can pass
/// `tracing_separate_thread = tracing::field::Empty` to the tracing macros. This is useful to
/// separate out spans which just indicate the current step or program frame being processed by the
/// interpreter. You should use a value of [tracing::field::Empty] so that other tracing layers
/// (e.g. the logger) will ignore the `tracing_separate_thread` field. For example:
/// ```rust
/// # use rustc_const_eval::enter_trace_span;
/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
/// let _span = enter_trace_span!(M, step::eval_statement, tracing_separate_thread = tracing::field::Empty);
/// ```
///
/// ### Executing something else when tracing is disabled
///
/// [crate::interpret::Machine::enter_trace_span] returns [EnteredTraceSpan], on which you can call
/// [EnteredTraceSpan::or_if_tracing_disabled], to e.g. log a line as an alternative to the tracing
/// span for when tracing is disabled. For example:
/// ```rust
/// # use rustc_const_eval::enter_trace_span;
/// # use rustc_const_eval::interpret::EnteredTraceSpan;
/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
/// let _span = enter_trace_span!(M, step::eval_statement)
/// .or_if_tracing_disabled(|| tracing::info!("eval_statement"));
/// ```
#[macro_export]
macro_rules! enter_trace_span {
($machine:ty, $name:ident :: $subname:ident $($tt:tt)*) => {
$crate::enter_trace_span!($machine, stringify!($name), $name = %stringify!($subname) $($tt)*)
};
($machine:ty, $($tt:tt)*) => {
<$machine as $crate::interpret::Machine>::enter_trace_span(|| tracing::info_span!($($tt)*))
};
}

View file

@ -4,8 +4,8 @@ version = "0.0.0"
edition = "2024"
[dependencies]
jiff = { version = "0.2.5", default-features = false, features = ["std"] }
# tidy-alphabetical-start
jiff = { version = "0.2.5", default-features = false, features = ["std"] }
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }

View file

@ -1,5 +1,4 @@
Abstract return types (written `impl Trait` for some trait `Trait`) are only
allowed as function and inherent impl return types.
`impl Trait` is only allowed as a function return and argument type.
Erroneous code example:
@ -14,7 +13,7 @@ fn main() {
}
```
Make sure `impl Trait` only appears in return-type position.
Make sure `impl Trait` appears in a function signature.
```
fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
@ -28,6 +27,6 @@ fn main() {
}
```
See [RFC 1522] for more details.
See the [reference] for more details on `impl Trait`.
[RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
[reference]: https://doc.rust-lang.org/stable/reference/types/impl-trait.html

View file

@ -10,7 +10,6 @@ derive_setters = "0.1.6"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_codes = { path = "../rustc_error_codes" }
rustc_error_messages = { path = "../rustc_error_messages" }
@ -25,7 +24,7 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_type_ir = { path = "../rustc_type_ir" }
serde = { version = "1.0.125", features = [ "derive" ] }
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"
termcolor = "1.2.0"
termize = "0.2"

View file

@ -8,7 +8,7 @@ use std::process::ExitStatus;
use rustc_abi::TargetDataLayoutErrors;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::RustcVersion;
use rustc_hir::RustcVersion;
use rustc_macros::Subdiagnostic;
use rustc_span::edition::Edition;
use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol};

View file

@ -262,19 +262,11 @@ pub trait Emitter {
format!("help: {msg}")
} else {
// Show the default suggestion text with the substitution
format!(
"help: {}{}: `{}`",
msg,
if self
.source_map()
.is_some_and(|sm| is_case_difference(sm, snippet, part.span,))
{
" (notice the capitalization)"
} else {
""
},
snippet,
)
let confusion_type = self
.source_map()
.map(|sm| detect_confusion_type(sm, snippet, part.span))
.unwrap_or(ConfusionType::None);
format!("help: {}{}: `{}`", msg, confusion_type.label_text(), snippet,)
};
primary_span.push_span_label(part.span, msg);
@ -1597,8 +1589,9 @@ impl HumanEmitter {
annotated_files.swap(0, pos);
}
let annotated_files_len = annotated_files.len();
// Print out the annotate source lines that correspond with the error
for annotated_file in annotated_files {
for (file_idx, annotated_file) in annotated_files.into_iter().enumerate() {
// we can't annotate anything if the source is unavailable.
if !should_show_source_code(
&self.ignored_directories_in_source_blocks,
@ -1855,7 +1848,9 @@ impl HumanEmitter {
width_offset,
code_offset,
margin,
!is_cont && line_idx + 1 == annotated_file.lines.len(),
!is_cont
&& file_idx + 1 == annotated_files_len
&& line_idx + 1 == annotated_file.lines.len(),
);
let mut to_add = FxHashMap::default();
@ -2028,12 +2023,12 @@ impl HumanEmitter {
buffer.append(0, ": ", Style::HeaderMsg);
let mut msg = vec![(suggestion.msg.to_owned(), Style::NoStyle)];
if suggestions
.iter()
.take(MAX_SUGGESTIONS)
.any(|(_, _, _, only_capitalization)| *only_capitalization)
if let Some(confusion_type) =
suggestions.iter().take(MAX_SUGGESTIONS).find_map(|(_, _, _, confusion_type)| {
if confusion_type.has_confusion() { Some(*confusion_type) } else { None }
})
{
msg.push((" (notice the capitalization difference)".into(), Style::NoStyle));
msg.push((confusion_type.label_text().into(), Style::NoStyle));
}
self.msgs_to_buffer(
&mut buffer,
@ -2985,7 +2980,7 @@ impl HumanEmitter {
fn secondary_file_start(&self) -> &'static str {
match self.theme {
OutputTheme::Ascii => "::: ",
OutputTheme::Unicode => " ",
OutputTheme::Unicode => " ",
}
}
@ -3528,24 +3523,107 @@ pub fn is_different(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
}
/// Whether the original and suggested code are visually similar enough to warrant extra wording.
pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
// FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
pub fn detect_confusion_type(sm: &SourceMap, suggested: &str, sp: Span) -> ConfusionType {
let found = match sm.span_to_snippet(sp) {
Ok(snippet) => snippet,
Err(e) => {
warn!(error = ?e, "Invalid span {:?}", sp);
return false;
return ConfusionType::None;
}
};
let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
// All the chars that differ in capitalization are confusable (above):
let confusable = iter::zip(found.chars(), suggested.chars())
.filter(|(f, s)| f != s)
.all(|(f, s)| ascii_confusables.contains(&f) || ascii_confusables.contains(&s));
confusable && found.to_lowercase() == suggested.to_lowercase()
// FIXME: We sometimes suggest the same thing we already have, which is a
// bug, but be defensive against that here.
&& found != suggested
let mut has_case_confusion = false;
let mut has_digit_letter_confusion = false;
if found.len() == suggested.len() {
let mut has_case_diff = false;
let mut has_digit_letter_confusable = false;
let mut has_other_diff = false;
let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
let digit_letter_confusables = [('0', 'O'), ('1', 'l'), ('5', 'S'), ('8', 'B'), ('9', 'g')];
for (f, s) in iter::zip(found.chars(), suggested.chars()) {
if f != s {
if f.to_lowercase().to_string() == s.to_lowercase().to_string() {
// Check for case differences (any character that differs only in case)
if ascii_confusables.contains(&f) || ascii_confusables.contains(&s) {
has_case_diff = true;
} else {
has_other_diff = true;
}
} else if digit_letter_confusables.contains(&(f, s))
|| digit_letter_confusables.contains(&(s, f))
{
// Check for digit-letter confusables (like 0 vs O, 1 vs l, etc.)
has_digit_letter_confusable = true;
} else {
has_other_diff = true;
}
}
}
// If we have case differences and no other differences
if has_case_diff && !has_other_diff && found != suggested {
has_case_confusion = true;
}
if has_digit_letter_confusable && !has_other_diff && found != suggested {
has_digit_letter_confusion = true;
}
}
match (has_case_confusion, has_digit_letter_confusion) {
(true, true) => ConfusionType::Both,
(true, false) => ConfusionType::Case,
(false, true) => ConfusionType::DigitLetter,
(false, false) => ConfusionType::None,
}
}
/// Represents the type of confusion detected between original and suggested code.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConfusionType {
/// No confusion detected
None,
/// Only case differences (e.g., "hello" vs "Hello")
Case,
/// Only digit-letter confusion (e.g., "0" vs "O", "1" vs "l")
DigitLetter,
/// Both case and digit-letter confusion
Both,
}
impl ConfusionType {
/// Returns the appropriate label text for this confusion type.
pub fn label_text(&self) -> &'static str {
match self {
ConfusionType::None => "",
ConfusionType::Case => " (notice the capitalization)",
ConfusionType::DigitLetter => " (notice the digit/letter confusion)",
ConfusionType::Both => " (notice the capitalization and digit/letter confusion)",
}
}
/// Combines two confusion types. If either is `Both`, the result is `Both`.
/// If one is `Case` and the other is `DigitLetter`, the result is `Both`.
/// Otherwise, returns the non-`None` type, or `None` if both are `None`.
pub fn combine(self, other: ConfusionType) -> ConfusionType {
match (self, other) {
(ConfusionType::None, other) => other,
(this, ConfusionType::None) => this,
(ConfusionType::Both, _) | (_, ConfusionType::Both) => ConfusionType::Both,
(ConfusionType::Case, ConfusionType::DigitLetter)
| (ConfusionType::DigitLetter, ConfusionType::Case) => ConfusionType::Both,
(ConfusionType::Case, ConfusionType::Case) => ConfusionType::Case,
(ConfusionType::DigitLetter, ConfusionType::DigitLetter) => ConfusionType::DigitLetter,
}
}
/// Returns true if this confusion type represents any kind of confusion.
pub fn has_confusion(&self) -> bool {
*self != ConfusionType::None
}
}
pub(crate) fn should_show_source_code(

View file

@ -50,7 +50,7 @@ pub use diagnostic_impls::{
IndicateAnonymousLifetime, SingleLabelManySpans,
};
pub use emitter::ColorConfig;
use emitter::{DynEmitter, Emitter, is_case_difference, is_different};
use emitter::{ConfusionType, DynEmitter, Emitter, detect_confusion_type, is_different};
use rustc_data_structures::AtomicRef;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::StableHasher;
@ -308,7 +308,7 @@ impl CodeSuggestion {
pub(crate) fn splice_lines(
&self,
sm: &SourceMap,
) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, bool)> {
) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, ConfusionType)> {
// For the `Vec<Vec<SubstitutionHighlight>>` value, the first level of the vector
// corresponds to the output snippet's lines, while the second level corresponds to the
// substrings within that line that should be highlighted.
@ -414,14 +414,15 @@ impl CodeSuggestion {
// We need to keep track of the difference between the existing code and the added
// or deleted code in order to point at the correct column *after* substitution.
let mut acc = 0;
let mut only_capitalization = false;
let mut confusion_type = ConfusionType::None;
for part in &mut substitution.parts {
// If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
// suggestion and snippet to look as if we just suggested to add
// `"b"`, which is typically much easier for the user to understand.
part.trim_trivial_replacements(sm);
only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
let part_confusion = detect_confusion_type(sm, &part.snippet, part.span);
confusion_type = confusion_type.combine(part_confusion);
let cur_lo = sm.lookup_char_pos(part.span.lo());
if prev_hi.line == cur_lo.line {
let mut count =
@ -511,7 +512,7 @@ impl CodeSuggestion {
if highlights.iter().all(|parts| parts.is_empty()) {
None
} else {
Some((buf, substitution.parts, highlights, only_capitalization))
Some((buf, substitution.parts, highlights, confusion_type))
}
})
.collect()

View file

@ -12,7 +12,6 @@ doctest = false
rustc_ast = { path = "../rustc_ast" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -12,12 +12,13 @@ use rustc_ast::token::MetaVarKind;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr_data_structures::{AttributeKind, CfgEntry, Deprecation, Stability, find_attr};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::sync;
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation};
use rustc_hir::{Stability, find_attr};
use rustc_lint_defs::{BufferedEarlyLint, RegisteredTools};
use rustc_parse::MACRO_ARGUMENTS;
use rustc_parse::parser::{ForceCollect, Parser};

View file

@ -1411,9 +1411,8 @@ impl InvocationCollectorNode for P<ast::Item> {
}
}
}
let mut idents = Vec::new();
collect_use_tree_leaves(ut, &mut idents);
collect_use_tree_leaves(&ut, &mut idents);
idents
} else {
self.kind.ident().into_iter().collect()

View file

@ -10,11 +10,12 @@ use rustc_ast::token::{self, NonterminalKind, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::find_attr;
use rustc_lint_defs::BuiltinLintDiag;
use rustc_lint_defs::builtin::{
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,

View file

@ -5,8 +5,8 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_hir = { path = "../rustc_hir" }
rustc_span = { path = "../rustc_span" }
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"

View file

@ -5,8 +5,8 @@ use std::sync::LazyLock;
use AttributeDuplicates::*;
use AttributeGate::*;
use AttributeType::*;
use rustc_attr_data_structures::EncodeCrossCrate;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::attrs::EncodeCrossCrate;
use rustc_span::edition::Edition;
use rustc_span::{Symbol, sym};
@ -112,7 +112,7 @@ pub enum AttributeGate {
Ungated,
}
// FIXME(jdonszelmann): move to rustc_attr_data_structures
// FIXME(jdonszelmann): move to rustc_hir::attrs
/// A template that the attribute input must match.
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
#[derive(Clone, Copy, Default)]
@ -1257,11 +1257,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),
DuplicatesOk, EncodeCrossCrate::No
),
gated!(
omit_gdb_pretty_printer_section, Normal, template!(Word),
WarnFollowing, EncodeCrossCrate::No,
"the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
),
rustc_attr!(
TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"),
ErrorFollowing, EncodeCrossCrate::No,

View file

@ -199,6 +199,8 @@ declare_features! (
/// Renamed to `dyn_compatible_for_dispatch`.
(removed, object_safe_for_dispatch, "1.83.0", Some(43561),
Some("renamed to `dyn_compatible_for_dispatch`"), 131511),
/// Allows using `#[omit_gdb_pretty_printer_section]`.
(removed, omit_gdb_pretty_printer_section, "CURRENT_RUSTC_VERSION", None, None, 144738),
/// Allows using `#[on_unimplemented(..)]` on traits.
/// (Moved to `rustc_attrs`.)
(removed, on_unimplemented, "1.40.0", None, None, 65794),

View file

@ -225,8 +225,6 @@ declare_features! (
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
(internal, negative_bounds, "1.71.0", None),
/// Allows using `#[omit_gdb_pretty_printer_section]`.
(internal, omit_gdb_pretty_printer_section, "1.5.0", None),
/// Set the maximum pattern complexity allowed (not limited by default).
(internal, pattern_complexity_limit, "1.78.0", None),
/// Allows using pattern types.

View file

@ -9,7 +9,7 @@ odht = { version = "0.3.1", features = ["nightly"] }
rustc_abi = { path = "../rustc_abi" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_hashes = { path = "../rustc_hashes" }
rustc_index = { path = "../rustc_index" }

View file

@ -1,12 +1,15 @@
pub use ReprAttr::*;
use rustc_abi::Align;
use rustc_ast::token::CommentKind;
use rustc_ast::{self as ast, AttrStyle};
use rustc_ast::{AttrStyle, ast};
use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
use rustc_span::def_id::DefId;
use rustc_span::hygiene::Transparency;
use rustc_span::{Ident, Span, Symbol};
use thin_vec::ThinVec;
use crate::{DefaultBodyStability, PartialConstStability, PrintAttribute, RustcVersion, Stability};
use crate::attrs::pretty_printing::PrintAttribute;
use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)]
pub enum InlineAttr {
@ -68,8 +71,6 @@ pub enum ReprAttr {
ReprTransparent,
ReprAlign(Align),
}
pub use ReprAttr::*;
use rustc_span::def_id::DefId;
pub enum TransparencyError {
UnknownTransparency(Symbol, Span),
@ -390,9 +391,6 @@ pub enum AttributeKind {
/// Represents `#[non_exhaustive]`
NonExhaustive(Span),
/// Represents `#[omit_gdb_pretty_printer_section]`
OmitGdbPrettyPrinterSection,
/// Represents `#[optimize(size|speed)]`
Optimize(OptimizeAttr, Span),

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