diff --git a/Cargo.lock b/Cargo.lock index ea93fbd01f069..4ea55456baade 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1491,6 +1491,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ + "allocator-api2", "foldhash", "serde", ] @@ -3044,13 +3045,6 @@ dependencies = [ "serde", ] -[[package]] -name = "rls" -version = "2.0.0" -dependencies = [ - "serde_json", -] - [[package]] name = "run_make_support" version = "0.2.0" @@ -3492,6 +3486,7 @@ dependencies = [ "either", "elsa", "ena", + "hashbrown 0.15.2", "indexmap", "jobserver", "libc", diff --git a/Cargo.toml b/Cargo.toml index 20a43aaaeeb37..915ec2e00ca44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ members = [ "src/tools/remote-test-server", "src/tools/rust-installer", "src/tools/rustdoc", - "src/tools/rls", "src/tools/rustfmt", "src/tools/miri", "src/tools/miri/cargo-miri", diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs index f4986d1d1872a..389d8c2413bfa 100644 --- a/compiler/rustc_attr_data_structures/src/lib.rs +++ b/compiler/rustc_attr_data_structures/src/lib.rs @@ -35,13 +35,17 @@ pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStabl /// like [`Span`]s and empty tuples, are gracefully skipped so they don't clutter the /// representation much. pub trait PrintAttribute { - fn print_something(&self) -> bool; + /// Whether or not this will render as something meaningful, or if it's skipped + /// (which will force the containing struct to also skip printing a comma + /// and the field name). + fn should_render(&self) -> bool; + fn print_attribute(&self, p: &mut Printer); } impl PrintAttribute for &T { - fn print_something(&self) -> bool { - T::print_something(self) + fn should_render(&self) -> bool { + T::should_render(self) } fn print_attribute(&self, p: &mut Printer) { @@ -49,9 +53,10 @@ impl PrintAttribute for &T { } } impl PrintAttribute for Option { - fn print_something(&self) -> bool { - self.as_ref().is_some_and(|x| x.print_something()) + fn should_render(&self) -> bool { + self.as_ref().is_some_and(|x| x.should_render()) } + fn print_attribute(&self, p: &mut Printer) { if let Some(i) = self { T::print_attribute(i, p) @@ -59,9 +64,10 @@ impl PrintAttribute for Option { } } impl PrintAttribute for ThinVec { - fn print_something(&self) -> bool { - self.is_empty() || self[0].print_something() + fn should_render(&self) -> bool { + self.is_empty() || self[0].should_render() } + fn print_attribute(&self, p: &mut Printer) { let mut last_printed = false; p.word("["); @@ -70,7 +76,7 @@ impl PrintAttribute for ThinVec { p.word_space(","); } i.print_attribute(p); - last_printed = i.print_something(); + last_printed = i.should_render(); } p.word("]"); } @@ -78,7 +84,7 @@ impl PrintAttribute for ThinVec { macro_rules! print_skip { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { false } + fn should_render(&self) -> bool { false } fn print_attribute(&self, _: &mut Printer) { } })* }; @@ -87,7 +93,7 @@ macro_rules! print_skip { macro_rules! print_disp { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { true } + fn should_render(&self) -> bool { true } fn print_attribute(&self, p: &mut Printer) { p.word(format!("{}", self)); } @@ -97,7 +103,7 @@ macro_rules! print_disp { macro_rules! print_debug { ($($t: ty),* $(,)?) => {$( impl PrintAttribute for $t { - fn print_something(&self) -> bool { true } + fn should_render(&self) -> bool { true } fn print_attribute(&self, p: &mut Printer) { p.word(format!("{:?}", self)); } @@ -106,37 +112,39 @@ macro_rules! print_debug { } macro_rules! print_tup { - (num_print_something $($ts: ident)*) => { 0 $(+ $ts.print_something() as usize)* }; + (num_should_render $($ts: ident)*) => { 0 $(+ $ts.should_render() as usize)* }; () => {}; ($t: ident $($ts: ident)*) => { #[allow(non_snake_case, unused)] impl<$t: PrintAttribute, $($ts: PrintAttribute),*> PrintAttribute for ($t, $($ts),*) { - fn print_something(&self) -> bool { + fn should_render(&self) -> bool { let ($t, $($ts),*) = self; - print_tup!(num_print_something $t $($ts)*) != 0 + print_tup!(num_should_render $t $($ts)*) != 0 } fn print_attribute(&self, p: &mut Printer) { let ($t, $($ts),*) = self; - let parens = print_tup!(num_print_something $t $($ts)*) > 1; + let parens = print_tup!(num_should_render $t $($ts)*) > 1; if parens { - p.word("("); + p.popen(); } - let mut printed_anything = $t.print_something(); + let mut printed_anything = $t.should_render(); $t.print_attribute(p); $( - if printed_anything && $ts.print_something() { - p.word_space(","); + if $ts.should_render() { + if printed_anything { + p.word_space(","); + } printed_anything = true; } $ts.print_attribute(p); )* if parens { - p.word(")"); + p.pclose(); } } } @@ -147,8 +155,8 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, ()); -print_disp!(Symbol, u16, bool, NonZero); -print_debug!(UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency); +print_disp!(u16, bool, NonZero); +print_debug!(Symbol, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency); /// Finds attributes in sequences of attributes by pattern matching. /// diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index d1f238331d56f..208d510db2e1f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -505,7 +505,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let var_id = self.infcx.tcx.closure_captures(def_id)[field.index()].get_root_variable(); - Some(self.infcx.tcx.hir().name(var_id).to_string()) + Some(self.infcx.tcx.hir_name(var_id).to_string()) } _ => { // Might need a revision when the fields in trait RFC is implemented @@ -1124,7 +1124,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { def_id, target_place, places ); let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id); - let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; + let expr = &self.infcx.tcx.hir_expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { for (captured_place, place) in diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 145137f923691..3951b467961a5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -698,7 +698,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if !matches!(k, hir::AssocItemKind::Fn { .. }) { continue; } - if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) { + if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) { continue; } f_in_trait_opt = Some(hi); diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index 876b8f214b017..7192a889adcbc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -105,7 +105,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Some(opaque_def_id) = opaque_def_id.as_local() && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = - tcx.hir().expect_opaque_ty(opaque_def_id).origin + tcx.hir_expect_opaque_ty(opaque_def_id).origin { if let Some(sugg) = impl_trait_overcapture_suggestion( tcx, diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index a15f9744bf310..412aaf70c3f19 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -343,7 +343,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } }; let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) = - tcx.hir().expect_expr(self.mir_hir_id()).kind + tcx.hir_expect_expr(self.mir_hir_id()).kind else { bug!("Closure is not defined by a closure expr"); }; diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 191c0444c742e..693d22abbe6c8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -69,7 +69,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let upvar_hir_id = upvars[upvar_index].get_root_variable(); debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}"); - let upvar_name = tcx.hir().name(upvar_hir_id); + let upvar_name = tcx.hir_name(upvar_hir_id); let upvar_span = tcx.hir().span(upvar_hir_id); debug!( "get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}", diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index b5f4f2efd1f5b..1289d21308b7a 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -3,10 +3,6 @@ name = "rustc_builtin_macros" version = "0.0.0" edition = "2024" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] } - [lib] doctest = false diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 32f689608f816..3710625ac12d7 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -63,7 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr }, }; - for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) { + for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) { ams.check_attr(attr); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 87992ce2e11b4..9cc737d194ce7 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -475,7 +475,7 @@ pub(crate) fn start_async_codegen( ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 63f2f8fa3d177..e9c886d28edf6 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -876,7 +876,7 @@ impl CrateInfo { let linked_symbols = crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect(); let local_crate_name = tcx.crate_name(LOCAL_CRATE); - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let subsystem = ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 90c53c347689b..97f0c6f73d5b1 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -62,7 +62,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { ); } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)); let mut codegen_fn_attrs = CodegenFnAttrs::new(); if tcx.should_inherit_track_caller(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; @@ -77,7 +77,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // When `no_builtins` is applied at the crate level, we should add the // `no-builtins` attribute to each function to ensure it takes effect in LTO. - let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); if no_builtins { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS; diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 607cb2e497d8d..06ee7075170ff 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -81,7 +81,7 @@ pub fn rustc_allow_const_fn_unstable( def_id: LocalDefId, feature_gate: Symbol, ) -> bool { - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate)) } diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index bdf5494f2107b..b9a5fc3a1fe9c 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -29,6 +29,11 @@ thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end +[dependencies.hashbrown] +version = "0.15.2" +default-features = false +features = ["nightly"] # for may_dangle + [dependencies.parking_lot] version = "0.12" diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index a3b62b469196a..865424fd6bbdc 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -24,7 +24,6 @@ #![feature(dropck_eyepatch)] #![feature(extend_one)] #![feature(file_buffered)] -#![feature(hash_raw_entry)] #![feature(macro_metavar_expr)] #![feature(map_try_insert)] #![feature(min_specialization)] diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 4cacc269709a9..64c64bfa3c296 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -76,6 +76,7 @@ impl_dyn_send!( [crate::sync::RwLock where T: DynSend] [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Send + crate::tagged_ptr::Tag] [rustc_arena::TypedArena where T: DynSend] + [hashbrown::HashTable where T: DynSend] [indexmap::IndexSet where V: DynSend, S: DynSend] [indexmap::IndexMap where K: DynSend, V: DynSend, S: DynSend] [thin_vec::ThinVec where T: DynSend] @@ -153,6 +154,7 @@ impl_dyn_sync!( [crate::tagged_ptr::TaggedRef<'a, P, T> where 'a, P: Sync, T: Sync + crate::tagged_ptr::Tag] [parking_lot::lock_api::Mutex where R: DynSync, T: ?Sized + DynSend] [parking_lot::lock_api::RwLock where R: DynSync, T: ?Sized + DynSend + DynSync] + [hashbrown::HashTable where T: DynSync] [indexmap::IndexSet where V: DynSync, S: DynSync] [indexmap::IndexMap where K: DynSync, V: DynSync, S: DynSync] [smallvec::SmallVec where A: smallvec::Array + DynSync] diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 3016348f22469..49cafcb17a03e 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -1,11 +1,11 @@ use std::borrow::Borrow; -use std::collections::hash_map::RawEntryMut; use std::hash::{Hash, Hasher}; -use std::iter; +use std::{iter, mem}; use either::Either; +use hashbrown::hash_table::{Entry, HashTable}; -use crate::fx::{FxHashMap, FxHasher}; +use crate::fx::FxHasher; use crate::sync::{CacheAligned, Lock, LockGuard, Mode, is_dyn_thread_safe}; // 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700, @@ -140,17 +140,67 @@ pub fn shards() -> usize { 1 } -pub type ShardedHashMap = Sharded>; +pub type ShardedHashMap = Sharded>; impl ShardedHashMap { pub fn with_capacity(cap: usize) -> Self { - Self::new(|| FxHashMap::with_capacity_and_hasher(cap, rustc_hash::FxBuildHasher::default())) + Self::new(|| HashTable::with_capacity(cap)) } pub fn len(&self) -> usize { self.lock_shards().map(|shard| shard.len()).sum() } } +impl ShardedHashMap { + #[inline] + pub fn get(&self, key: &Q) -> Option + where + K: Borrow, + Q: Hash + Eq, + V: Clone, + { + let hash = make_hash(key); + let shard = self.lock_shard_by_hash(hash); + let (_, value) = shard.find(hash, |(k, _)| k.borrow() == key)?; + Some(value.clone()) + } + + #[inline] + pub fn get_or_insert_with(&self, key: K, default: impl FnOnce() -> V) -> V + where + V: Copy, + { + let hash = make_hash(&key); + let mut shard = self.lock_shard_by_hash(hash); + + match table_entry(&mut shard, hash, &key) { + Entry::Occupied(e) => e.get().1, + Entry::Vacant(e) => { + let value = default(); + e.insert((key, value)); + value + } + } + } + + #[inline] + pub fn insert(&self, key: K, value: V) -> Option { + let hash = make_hash(&key); + let mut shard = self.lock_shard_by_hash(hash); + + match table_entry(&mut shard, hash, &key) { + Entry::Occupied(e) => { + let previous = mem::replace(&mut e.into_mut().1, value); + Some(previous) + } + Entry::Vacant(e) => { + e.insert((key, value)); + None + } + } + } +} + impl ShardedHashMap { #[inline] pub fn intern_ref(&self, value: &Q, make: impl FnOnce() -> K) -> K @@ -160,13 +210,12 @@ impl ShardedHashMap { { let hash = make_hash(value); let mut shard = self.lock_shard_by_hash(hash); - let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, value); - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { + match table_entry(&mut shard, hash, value) { + Entry::Occupied(e) => e.get().0, + Entry::Vacant(e) => { let v = make(); - e.insert_hashed_nocheck(hash, v, ()); + e.insert((v, ())); v } } @@ -180,13 +229,12 @@ impl ShardedHashMap { { let hash = make_hash(&value); let mut shard = self.lock_shard_by_hash(hash); - let entry = shard.raw_entry_mut().from_key_hashed_nocheck(hash, &value); - match entry { - RawEntryMut::Occupied(e) => *e.key(), - RawEntryMut::Vacant(e) => { + match table_entry(&mut shard, hash, &value) { + Entry::Occupied(e) => e.get().0, + Entry::Vacant(e) => { let v = make(value); - e.insert_hashed_nocheck(hash, v, ()); + e.insert((v, ())); v } } @@ -203,17 +251,30 @@ impl ShardedHashMap { let hash = make_hash(&value); let shard = self.lock_shard_by_hash(hash); let value = value.into_pointer(); - shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some() + shard.find(hash, |(k, ())| k.into_pointer() == value).is_some() } } #[inline] -pub fn make_hash(val: &K) -> u64 { +fn make_hash(val: &K) -> u64 { let mut state = FxHasher::default(); val.hash(&mut state); state.finish() } +#[inline] +fn table_entry<'a, K, V, Q>( + table: &'a mut HashTable<(K, V)>, + hash: u64, + key: &Q, +) -> Entry<'a, (K, V)> +where + K: Hash + Borrow, + Q: ?Sized + Eq, +{ + table.entry(hash, move |(k, _)| k.borrow() == key, |(k, _)| make_hash(k)) +} + /// Get a shard with a pre-computed hash value. If `get_shard_by_value` is /// ever used in combination with `get_shard_by_hash` on a single `Sharded` /// instance, then `hash` must be computed with `FxHasher`. Otherwise, diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 828a14e707c50..16d70af7e05d8 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -268,8 +268,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let tcx = ex.tcx(); let f = |annotation: &dyn pprust_hir::PpAnn| { let sm = sess.source_map(); - let hir_map = tcx.hir(); - let attrs = |id| hir_map.attrs(id); + let attrs = |id| tcx.hir_attrs(id); pprust_hir::print_crate( sm, tcx.hir_root_module(), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 7741f6668c382..3c61bfd1c93f5 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -240,7 +240,7 @@ declare_features! ( /// Added for testing unstable lints; perma-unstable. (internal, test_unstable_lint, "1.60.0", None), /// Helps with formatting for `group_imports = "StdExternalCrate"`. - (unstable, unqualified_local_imports, "1.83.0", None), + (unstable, unqualified_local_imports, "1.83.0", Some(138299)), /// Use for stable + negative coherence and strict coherence depending on trait's /// rustc_strict_coherence value. (unstable, with_negative_coherence, "1.60.0", None), diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 928455ace8562..69327ca3c0083 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3368,13 +3368,16 @@ pub struct OpaqueTy<'hir> { pub span: Span, } -#[derive(Debug, Clone, Copy, HashStable_Generic)] -pub enum PreciseCapturingArg<'hir> { - Lifetime(&'hir Lifetime), +#[derive(Debug, Clone, Copy, HashStable_Generic, Encodable, Decodable)] +pub enum PreciseCapturingArgKind { + Lifetime(T), /// Non-lifetime argument (type or const) - Param(PreciseCapturingNonLifetimeArg), + Param(U), } +pub type PreciseCapturingArg<'hir> = + PreciseCapturingArgKind<&'hir Lifetime, PreciseCapturingNonLifetimeArg>; + impl PreciseCapturingArg<'_> { pub fn hir_id(self) -> HirId { match self { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8f9997cb62ca4..54eaea5d7c1cb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -185,7 +185,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) { /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo` /// projections that would result in "inheriting lifetimes". fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let hir::OpaqueTy { origin, .. } = *tcx.hir().expect_opaque_ty(def_id); + let hir::OpaqueTy { origin, .. } = *tcx.hir_expect_opaque_ty(def_id); // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting // `async-std` (and `pub async fn` in general). @@ -791,7 +791,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_type_alias_type_params_are_used(tcx, def_id); } DefKind::ForeignMod => { - let it = tcx.hir().expect_item(def_id); + let it = tcx.hir_expect_item(def_id); let hir::ItemKind::ForeignMod { abi, items } = it.kind else { return; }; diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c193aad2afd00..0a37a27b35bab 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1031,7 +1031,7 @@ fn report_trait_method_mismatch<'tcx>( // When the `impl` receiver is an arbitrary self type, like `self: Box`, the // span points only at the type `Box, but we want to cover the whole // argument pattern and type. - let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) @@ -1051,7 +1051,7 @@ fn report_trait_method_mismatch<'tcx>( // Suggestion to change output type. We do not suggest in `async` functions // to avoid complex logic or incorrect output. if let ImplItemKind::Fn(sig, _) = - &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind + &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).kind && !sig.header.asyncness.is_async() { let msg = "change the output type to match the trait"; @@ -1190,12 +1190,12 @@ fn extract_spans_for_error_reporting<'tcx>( ) -> (Span, Option) { let tcx = infcx.tcx; let mut impl_args = { - let (sig, _) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (sig, _) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }; let trait_args = trait_m.def_id.as_local().map(|def_id| { - let (sig, _) = tcx.hir().expect_trait_item(def_id).expect_fn(); + let (sig, _) = tcx.hir_expect_trait_item(def_id).expect_fn(); sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span())) }); @@ -1371,7 +1371,7 @@ fn compare_number_of_generics<'tcx>( spans }; let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { - let trait_item = tcx.hir().expect_trait_item(def_id); + let trait_item = tcx.hir_expect_trait_item(def_id); let arg_spans: Vec = arg_spans(trait_.kind, trait_item.generics); let impl_trait_spans: Vec = trait_item .generics @@ -1388,7 +1388,7 @@ fn compare_number_of_generics<'tcx>( (trait_span.map(|s| vec![s]), vec![]) }; - let impl_item = tcx.hir().expect_impl_item(impl_.def_id.expect_local()); + let impl_item = tcx.hir_expect_impl_item(impl_.def_id.expect_local()); let impl_item_impl_trait_spans: Vec = impl_item .generics .params @@ -1466,7 +1466,7 @@ fn compare_number_of_method_arguments<'tcx>( .def_id .as_local() .and_then(|def_id| { - let (trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).expect_fn(); + let (trait_m_sig, _) = &tcx.hir_expect_trait_item(def_id).expect_fn(); let pos = trait_number_args.saturating_sub(1); trait_m_sig.decl.inputs.get(pos).map(|arg| { if pos == 0 { @@ -1478,7 +1478,7 @@ fn compare_number_of_method_arguments<'tcx>( }) .or_else(|| tcx.hir().span_if_local(trait_m.def_id)); - let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); + let (impl_m_sig, _) = &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let pos = impl_number_args.saturating_sub(1); let impl_span = impl_m_sig .decl @@ -1580,10 +1580,10 @@ fn compare_synthetic_generics<'tcx>( // as another generic argument let new_name = tcx.opt_item_name(trait_def_id)?; let trait_m = trait_m.def_id.as_local()?; - let trait_m = tcx.hir().expect_trait_item(trait_m); + let trait_m = tcx.hir_expect_trait_item(trait_m); let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); // in case there are no generics, take the spot between the function name // and the opening paren of the argument list @@ -1613,7 +1613,7 @@ fn compare_synthetic_generics<'tcx>( err.span_label(impl_span, "expected `impl Trait`, found generic parameter"); let _: Option<_> = try { let impl_m = impl_m.def_id.as_local()?; - let impl_m = tcx.hir().expect_impl_item(impl_m); + let impl_m = tcx.hir_expect_impl_item(impl_m); let (sig, _) = impl_m.expect_fn(); let input_tys = sig.decl.inputs; @@ -1855,7 +1855,7 @@ fn compare_const_predicate_entailment<'tcx>( debug!(?impl_ty, ?trait_ty); // Locate the Span containing just the type of the offending impl - let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const(); cause.span = ty.span; let mut diag = struct_span_code_err!( @@ -1868,7 +1868,7 @@ fn compare_const_predicate_entailment<'tcx>( let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { // Add a label to the Span containing just the type of the const - let (ty, _) = tcx.hir().expect_trait_item(trait_ct_def_id).expect_const(); + let (ty, _) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const(); ty.span }); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a400aaa814279..fd5ffdc2d7a4a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -513,7 +513,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { continue; } - let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id); + let gat_item_hir = tcx.hir_expect_trait_item(gat_def_id); debug!(?required_bounds); let param_env = tcx.param_env(gat_def_id); diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 750c09887a1e5..464ffa8711a53 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -31,7 +31,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { if used_trait_imports.contains(&id) { continue; } - let item = tcx.hir().expect_item(id); + let item = tcx.hir_expect_item(id); if item.span.is_dummy() { continue; } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index cee2f487639db..c918abe4c0755 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -82,7 +82,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran _ => {} } - let impl_ = tcx.hir().expect_item(impl_did).expect_impl(); + let impl_ = tcx.hir_expect_item(impl_did).expect_impl(); Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span })) } @@ -109,7 +109,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) { Ok(()) => Ok(()), Err(CopyImplementationError::InfringingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -119,15 +119,15 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran )) } Err(CopyImplementationError::NotAnAdt) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } Err(CopyImplementationError::HasDestructor) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) } Err(CopyImplementationError::HasUnsafeFields) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx .dcx() .span_delayed_bug(span, format!("cannot implement `Copy` for `{}`", self_type))) @@ -157,7 +157,7 @@ fn visit_implementation_of_const_param_ty( match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) { Ok(()) => Ok(()), Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)), @@ -167,11 +167,11 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span })) } Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(infringing_fields_error( tcx, infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)), @@ -181,7 +181,7 @@ fn visit_implementation_of_const_param_ty( )) } Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => { - let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span; + let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span; Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span })) } } @@ -526,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( note: true, })); } else if diff_fields.len() > 1 { - let item = tcx.hir().expect_item(impl_did); + let item = tcx.hir_expect_item(impl_did); let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind { t.path.span } else { diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index dbf7a7378f5ab..0b7fc44460ead 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -376,7 +376,7 @@ fn emit_orphan_check_error<'tcx>( ) -> ErrorGuaranteed { match err { traits::OrphanCheckErr::NonLocalInputType(tys) => { - let item = tcx.hir().expect_item(impl_def_id); + let item = tcx.hir_expect_item(impl_def_id); let impl_ = item.expect_impl(); let hir_trait_ref = impl_.of_trait.as_ref().unwrap(); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 49523912b14d3..e0e435dd6f0e7 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -28,7 +28,7 @@ use rustc_errors::{ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics}; -use rustc_hir::{self as hir, GenericParamKind, HirId, Node}; +use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; @@ -469,8 +469,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => { let item = self .tcx - .hir() - .expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); + .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { hir::ItemKind::Enum(_, generics) | hir::ItemKind::Struct(_, generics) @@ -1143,7 +1142,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { } fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let (is_alias, is_auto, safety, items) = match item.kind { hir::ItemKind::Trait(is_auto, safety, .., items) => { @@ -1342,7 +1341,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn ), ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => { - let abi = tcx.hir().get_foreign_abi(hir_id); + let abi = tcx.hir_get_foreign_abi(hir_id); compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety()) } @@ -1597,7 +1596,7 @@ pub fn suggest_impl_trait<'tcx>( fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option> { let icx = ItemCtxt::new(tcx, def_id); - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); let impl_ = item.expect_impl(); impl_.of_trait.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id).instantiate_identity(); @@ -1792,7 +1791,7 @@ fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueT fn rendered_precise_capturing_args<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> Option<&'tcx [Symbol]> { +) -> Option<&'tcx [PreciseCapturingArgKind]> { if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) = tcx.opt_rpitit_info(def_id.to_def_id()) { @@ -1801,7 +1800,12 @@ fn rendered_precise_capturing_args<'tcx>( tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound { hir::GenericBound::Use(args, ..) => { - Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name()))) + Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg { + PreciseCapturingArgKind::Lifetime(_) => { + PreciseCapturingArgKind::Lifetime(arg.name()) + } + PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()), + }))) } _ => None, }) diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 4debd3977f50a..7cbd31de6bab2 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -13,7 +13,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { for id in tcx.hir_crate_items(()).opaques() { if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. } | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = - tcx.hir().expect_opaque_ty(id).origin + tcx.hir_expect_opaque_ty(id).origin && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id) && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn() { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 6936544838c81..16caa4f6874c7 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -480,5 +480,5 @@ pub(crate) fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> } } } - HasTait.visit_ty_unambig(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break() + HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break() } diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 4dbdfa3d85a9b..cb711ebb91a8e 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -404,7 +404,7 @@ fn check_constraints<'tcx>( }; if let Some(local_sig_id) = sig_id.as_local() - && tcx.hir().opt_delegation_sig_id(local_sig_id).is_some() + && tcx.hir_opt_delegation_sig_id(local_sig_id).is_some() { emit("recursive delegation is not supported yet"); } @@ -416,7 +416,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, ) -> &'tcx [Ty<'tcx>] { - let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap(); + let sig_id = tcx.hir_opt_delegation_sig_id(def_id).unwrap(); let caller_sig = tcx.fn_sig(sig_id); if let Err(err) = check_constraints(tcx, def_id, sig_id) { let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index ace5e34b38249..fa061c806180f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1520,7 +1520,7 @@ fn generics_args_err_extend<'a>( }) .collect(); if args.len() > 1 - && let Some(span) = args.into_iter().last() + && let Some(span) = args.into_iter().next_back() { err.note( "generic arguments are not allowed on both an enum and its variant's path \ diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index dd6c40bfbb8dc..15f46fb38e318 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -370,7 +370,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip(self), ret)] pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> { let tcx = self.tcx(); - let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id)); + let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id)); match resolved { rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2572ff50eb74f..163d9a1b9d975 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -118,9 +118,9 @@ impl<'a> State<'a> { self.hardbreak() } hir::Attribute::Parsed(pa) => { - self.word("#[attr=\""); + self.word("#[attr = "); pa.print_attribute(self); - self.word("\")]"); + self.word("]"); self.hardbreak() } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 5e00161f693f6..2a24d626ac357 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -799,7 +799,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Emit a different diagnostic for local variables, as they are not // type definitions themselves, but rather variables *of* that type. Res::Local(hir_id) => { - err.arg("local_name", self.tcx.hir().name(hir_id)); + err.arg("local_name", self.tcx.hir_name(hir_id)); Some(fluent_generated::hir_typeck_invalid_local) } Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 786e8b876a613..96ae35f8e8b1e 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); + debug!("type of {} is...", self.tcx.hir_id_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); ty diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 9ff7eeb23688c..63e4a8fb44bda 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1235,7 +1235,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.cx.tainted_by_errors()?; bug!( "no type for node {} in mem_categorization", - self.cx.tcx().hir().node_to_string(id) + self.cx.tcx().hir_id_to_string(id) ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c46a42c5de1e3..1f218ab367442 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { - span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) + span_bug!(span, "no type for local variable {}", self.tcx.hir_id_to_string(nid)) }) } @@ -552,11 +552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), None => { - bug!( - "no type for node {} in fcx {}", - self.tcx.hir().node_to_string(id), - self.tag() - ); + bug!("no type for node {} in fcx {}", self.tcx.hir_id_to_string(id), self.tag()); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 35a3491f7c089..37aaaed5477dd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -613,7 +613,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .take(4) .map(|(var_hir_id, upvar)| { - let var_name = self.tcx.hir().name(*var_hir_id).to_string(); + let var_name = self.tcx.hir_name(*var_hir_id).to_string(); let msg = format!("`{var_name}` captured here"); (upvar.span, msg) }) diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs index 69d7a6c97cb36..72f8793d78399 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs @@ -363,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let import_items: Vec<_> = applicable_trait .import_ids .iter() - .map(|&import_id| self.tcx.hir().expect_item(import_id)) + .map(|&import_id| self.tcx.hir_expect_item(import_id)) .collect(); // Find an identifier with which this trait was imported (note that `_` doesn't count). diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index f87e5b5202ab5..ee01d78965d5c 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -2344,7 +2344,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return false; }; let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.fcx.tcx.hir().attrs(hir_id); + let attrs = self.fcx.tcx.hir_attrs(hir_id); for attr in attrs { if sym::doc == attr.name_or_empty() { } else if sym::rustc_confusables == attr.name_or_empty() { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index cb1e89fb9e593..1a1540f505d37 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -791,7 +791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Ok(pick) = self.lookup_probe_for_diagnostic( item_name, Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl), - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), + self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)), ProbeScope::TraitsInScope, None, ) @@ -834,8 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { - let call_expr = - self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)); let probe = self.lookup_probe_for_diagnostic( item_name, output_ty, @@ -2373,7 +2372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(item_name.span) { err.span_suggestion( @@ -2680,7 +2679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mod_id, expr.hir_id, ) { - let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)); + let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(expr.hir_id)); let lang_items = self.tcx.lang_items(); let never_mention_traits = [ @@ -2757,7 +2756,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::MethodCall(expr) = source else { return; }; - let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id)); + let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id)); let ty::Adt(kind, args) = actual.kind() else { return; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index f570d0d8a0d30..37f3786c00abc 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -781,7 +781,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id, base => bug!("Expected upvar, found={:?}", base), }; - let var_ident = self.tcx.hir().ident(var_hir_id); + let var_ident = self.tcx.hir_ident(var_hir_id); let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else { let mutability = self.determine_capture_mutability(&typeck_results, &place); @@ -988,13 +988,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => { let cause_span = self.tcx.hir().span(*capture_expr_id); lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span } => { lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), )); } @@ -1009,13 +1009,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", - self.tcx.hir().name(*var_hir_id), + self.tcx.hir_name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span: _ } => { lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", - v = self.tcx.hir().name(*var_hir_id), + v = self.tcx.hir_name(*var_hir_id), )); } } @@ -1026,7 +1026,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not capturing something anymore cannot cause a trait to fail to be implemented: match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { - let var_name = self.tcx.hir().name(*var_hir_id); + let var_name = self.tcx.hir_name(*var_hir_id); lint.span_label(closure_head_span, format!("\ in Rust 2018, this closure implements {missing_trait} \ as `{var_name}` implements {missing_trait}, but in Rust 2021, \ @@ -2300,7 +2300,7 @@ fn construct_capture_info_string<'tcx>( } fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol { - tcx.hir().name(var_hir_id) + tcx.hir_name(var_hir_id) } #[instrument(level = "debug", skip(tcx))] diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 8f2ca6babea88..1b2056f541f3e 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -123,7 +123,7 @@ impl<'tcx> IfThisChanged<'tcx> { fn process_attrs(&mut self, def_id: LocalDefId) { let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id()); let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { if attr.has_name(sym::rustc_if_this_changed) { let dep_node_interned = self.argument(attr); diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index 00600abb5f1e3..a2c1f1dbeda6b 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -8,7 +8,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { let mut decls = None; for id in tcx.hir_free_items() { - let attrs = tcx.hir().attrs(id.hir_id()); + let attrs = tcx.hir_attrs(id.hir_id()); if attr::contains_name(attrs, sym::rustc_proc_macro_decls) { decls = Some(id.owner_id.def_id); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index f7be37dc4a2c3..918a42f304780 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -419,7 +419,7 @@ impl MissingDoc { return; } - let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id)); + let attrs = cx.tcx.hir_attrs(cx.tcx.local_def_id_to_hir_id(def_id)); let has_doc = attrs.iter().any(has_doc); if !has_doc { cx.emit_span_lint( @@ -997,7 +997,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute, impl_generics: Option<&hir::Generics<'_>>, generics: &hir::Generics<'_>, @@ -1050,7 +1050,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { for it in *items { if let hir::AssocItemKind::Fn { .. } = it.kind { if let Some(no_mangle_attr) = - attr::find_by_name(cx.tcx.hir().attrs(it.id.hir_id()), sym::no_mangle) + attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle) { check_no_mangle_on_generic_fn( no_mangle_attr, diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 9ca148e1f2549..4c2b82a9a23a6 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -38,7 +38,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { } LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok. - let attr_id = tcx.hir().attrs(hir_id)[attr_index as usize].id(); + let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id(); (attr_id, lint_index) } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 23d6efa050836..852bb01c09655 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -48,7 +48,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { where F: FnOnce(&mut Self), { - let attrs = self.context.tcx.hir().attrs(id); + let attrs = self.context.tcx.hir_attrs(id); let prev = self.context.last_node_with_lint_attrs; self.context.last_node_with_lint_attrs = id; debug!("late context: enter_attrs({:?})", attrs); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 4ede9b4408798..aa6eef906ea42 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -152,7 +152,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { #[instrument(level = "trace", skip(tcx), ret)] fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap { let store = unerased_lint_store(tcx.sess); - let attrs = tcx.hir_attrs(owner); + let attrs = tcx.hir_attr_map(owner); let mut levels = LintLevelsBuilder { sess: tcx.sess, diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 49f9ad39780a3..722779d326891 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -342,8 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) - .and_then(|attr| { + ast::attr::find_by_name(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then( + |attr| { if let Attribute::Unparsed(n) = attr && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: lit }, .. } = n.as_ref() @@ -371,7 +371,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { } else { None } - }) + }, + ) }; if let Some(ident) = &crate_ident { @@ -500,7 +501,7 @@ impl NonUpperCaseGlobals { impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); match it.kind { hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => { NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident); diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index fcadbfc3c4a7e..6f3c32af5ef59 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1589,7 +1589,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations { fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) { let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration }; - let abi = cx.tcx.hir().get_foreign_abi(it.hir_id()); + let abi = cx.tcx.hir_get_foreign_abi(it.hir_id()); match it.kind { hir::ForeignItemKind::Fn(sig, _, _) => { diff --git a/compiler/rustc_macros/src/print_attribute.rs b/compiler/rustc_macros/src/print_attribute.rs index 3c6e30b851bf7..42d94e72ee942 100644 --- a/compiler/rustc_macros/src/print_attribute.rs +++ b/compiler/rustc_macros/src/print_attribute.rs @@ -16,12 +16,14 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok let name = field.ident.as_ref().unwrap(); let string_name = name.to_string(); disps.push(quote! { - if __printed_anything && #name.print_something() { - __p.word_space(","); + if #name.should_render() { + if __printed_anything { + __p.word_space(","); + } + __p.word(#string_name); + __p.word_space(":"); __printed_anything = true; } - __p.word(#string_name); - __p.word_space(":"); #name.print_attribute(__p); }); field_names.push(name); @@ -31,10 +33,11 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok quote! { {#(#field_names),*} }, quote! { __p.word(#string_name); - if true #(&& !#field_names.print_something())* { + if true #(&& !#field_names.should_render())* { return; } + __p.nbsp(); __p.word("{"); #(#disps)* __p.word("}"); @@ -48,8 +51,10 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok for idx in 0..fields_unnamed.unnamed.len() { let name = format_ident!("f{idx}"); disps.push(quote! { - if __printed_anything && #name.print_something() { - __p.word_space(","); + if #name.should_render() { + if __printed_anything { + __p.word_space(","); + } __printed_anything = true; } #name.print_attribute(__p); @@ -62,13 +67,13 @@ fn print_fields(name: &Ident, fields: &Fields) -> (TokenStream, TokenStream, Tok quote! { __p.word(#string_name); - if true #(&& !#field_names.print_something())* { + if true #(&& !#field_names.should_render())* { return; } - __p.word("("); + __p.popen(); #(#disps)* - __p.word(")"); + __p.pclose(); }, quote! { true }, ) @@ -138,7 +143,7 @@ pub(crate) fn print_attribute(input: Structure<'_>) -> TokenStream { input.gen_impl(quote! { #[allow(unused)] gen impl PrintAttribute for @Self { - fn print_something(&self) -> bool { #printed } + fn should_render(&self) -> bool { #printed } fn print_attribute(&self, __p: &mut rustc_ast_pretty::pp::Printer) { #code } } }) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 88a88847e6b8b..57c941976e44b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1357,8 +1357,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { features: &tcx.features(), }; let attr_iter = tcx - .hir() - .attrs(tcx.local_def_id_to_hir_id(def_id)) + .hir_attrs(tcx.local_def_id_to_hir_id(def_id)) .iter() .filter(|attr| analyze_attr(*attr, &mut state)); @@ -1839,7 +1838,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_macro(&mut self, def_id: LocalDefId) { let tcx = self.tcx; - let hir::ItemKind::Macro(macro_def, _) = tcx.hir().expect_item(def_id).kind else { bug!() }; + let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() }; self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules); record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body); } @@ -1918,11 +1917,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &proc_macro in &tcx.resolutions(()).proc_macros { let id = proc_macro; let proc_macro = tcx.local_def_id_to_hir_id(proc_macro); - let mut name = hir.name(proc_macro); + let mut name = tcx.hir_name(proc_macro); let span = hir.span(proc_macro); // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. - let attrs = hir.attrs(proc_macro); + let attrs = tcx.hir_attrs(proc_macro); let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) { MacroKind::Bang } else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 7b34e605c5307..5536c93f84a43 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -10,6 +10,7 @@ use rustc_abi::{FieldIdx, ReprOptions, VariantIdx}; use rustc_ast::expand::StrippedCfgItem; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; +use rustc_hir::PreciseCapturingArgKind; use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, StableCrateId}; use rustc_hir::definitions::DefKey; @@ -440,7 +441,7 @@ define_tables! { coerce_unsized_info: Table>, mir_const_qualif: Table>, rendered_const: Table>, - rendered_precise_capturing_args: Table>, + rendered_precise_capturing_args: Table>>, asyncness: Table, fn_arg_names: Table>, coroutine_kind: Table, diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index c85af81ee25bd..73c0af84a9fde 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -275,7 +275,7 @@ impl<'tcx> TyCtxt<'tcx> { span_bug!( self.hir().span(hir_id), "body_owned_by: {} has no associated body", - self.hir().node_to_string(hir_id) + self.hir_id_to_string(hir_id) ); }) } @@ -374,7 +374,7 @@ impl<'tcx> TyCtxt<'tcx> { /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { - self.hir().attrs(CRATE_HIR_ID) + self.hir_attrs(CRATE_HIR_ID) } pub fn hir_rustc_coherence_is_core(self) -> bool { @@ -674,104 +674,178 @@ impl<'tcx> TyCtxt<'tcx> { } } } -} -impl<'hir> Map<'hir> { - pub fn get_foreign_abi(self, hir_id: HirId) -> ExternAbi { - let parent = self.tcx.hir_get_parent_item(hir_id); + /// Get a representation of this `id` for debugging purposes. + /// NOTE: Do NOT use this in diagnostics! + pub fn hir_id_to_string(self, id: HirId) -> String { + let path_str = |def_id: LocalDefId| self.def_path_str(def_id); + + let span_str = || { + self.sess.source_map().span_to_snippet(Map { tcx: self }.span(id)).unwrap_or_default() + }; + let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); + + match self.hir_node(id) { + Node::Item(item) => { + let item_str = match item.kind { + ItemKind::ExternCrate(..) => "extern crate", + ItemKind::Use(..) => "use", + ItemKind::Static(..) => "static", + ItemKind::Const(..) => "const", + ItemKind::Fn { .. } => "fn", + ItemKind::Macro(..) => "macro", + ItemKind::Mod(..) => "mod", + ItemKind::ForeignMod { .. } => "foreign mod", + ItemKind::GlobalAsm { .. } => "global asm", + ItemKind::TyAlias(..) => "ty", + ItemKind::Enum(..) => "enum", + ItemKind::Struct(..) => "struct", + ItemKind::Union(..) => "union", + ItemKind::Trait(..) => "trait", + ItemKind::TraitAlias(..) => "trait alias", + ItemKind::Impl { .. } => "impl", + }; + format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) + } + Node::ForeignItem(item) => { + format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) + } + Node::ImplItem(ii) => { + let kind = match ii.kind { + ImplItemKind::Const(..) => "associated constant", + ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "method", + }, + ImplItemKind::Type(_) => "associated type", + }; + format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) + } + Node::TraitItem(ti) => { + let kind = match ti.kind { + TraitItemKind::Const(..) => "associated constant", + TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { + ImplicitSelfKind::None => "associated function", + _ => "trait method", + }, + TraitItemKind::Type(..) => "associated type", + }; + + format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) + } + Node::Variant(variant) => { + format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) + } + Node::Field(field) => { + format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) + } + Node::AnonConst(_) => node_str("const"), + Node::ConstBlock(_) => node_str("const"), + Node::ConstArg(_) => node_str("const"), + Node::Expr(_) => node_str("expr"), + Node::ExprField(_) => node_str("expr field"), + Node::Stmt(_) => node_str("stmt"), + Node::PathSegment(_) => node_str("path segment"), + Node::Ty(_) => node_str("type"), + Node::AssocItemConstraint(_) => node_str("assoc item constraint"), + Node::TraitRef(_) => node_str("trait ref"), + Node::OpaqueTy(_) => node_str("opaque type"), + Node::Pat(_) => node_str("pat"), + Node::TyPat(_) => node_str("pat ty"), + Node::PatField(_) => node_str("pattern field"), + Node::PatExpr(_) => node_str("pattern literal"), + Node::Param(_) => node_str("param"), + Node::Arm(_) => node_str("arm"), + Node::Block(_) => node_str("block"), + Node::Infer(_) => node_str("infer"), + Node::LetStmt(_) => node_str("local"), + Node::Ctor(ctor) => format!( + "{id} (ctor {})", + ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), + ), + Node::Lifetime(_) => node_str("lifetime"), + Node::GenericParam(param) => { + format!("{id} (generic_param {})", path_str(param.def_id)) + } + Node::Crate(..) => String::from("(root_crate)"), + Node::WherePredicate(_) => node_str("where predicate"), + Node::Synthetic => unreachable!(), + Node::Err(_) => node_str("error"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), + } + } + + pub fn hir_get_foreign_abi(self, hir_id: HirId) -> ExternAbi { + let parent = self.hir_get_parent_item(hir_id); if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = - self.tcx.hir_owner_node(parent) + self.hir_owner_node(parent) { return *abi; } bug!( "expected foreign mod or inlined parent, found {}", - self.node_to_string(HirId::make_owner(parent.def_id)) + self.hir_id_to_string(HirId::make_owner(parent.def_id)) ) } - pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_item(self, id: LocalDefId) -> &'tcx Item<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::Item(item) => item, - _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!("expected item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_impl_item(self, id: LocalDefId) -> &'tcx ImplItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::ImplItem(item) => item, - _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), + _ => bug!("expected impl item, found {}", self.hir_id_to_string(HirId::make_owner(id))), } } - pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> { - match self.tcx.expect_hir_owner_node(id) { + pub fn hir_expect_trait_item(self, id: LocalDefId) -> &'tcx TraitItem<'tcx> { + match self.expect_hir_owner_node(id) { OwnerNode::TraitItem(item) => item, - _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), - } - } - - pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> { - Some(&self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.output) - } - - pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { - match self.tcx.hir_node(id) { - Node::Variant(variant) => variant, - _ => bug!("expected variant, found {}", self.node_to_string(id)), - } - } - - pub fn expect_field(self, id: HirId) -> &'hir FieldDef<'hir> { - match self.tcx.hir_node(id) { - Node::Field(field) => field, - _ => bug!("expected field, found {}", self.node_to_string(id)), - } - } - - pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> { - match self.tcx.hir_owner_node(id) { - OwnerNode::ForeignItem(item) => item, _ => { - bug!( - "expected foreign item, found {}", - self.node_to_string(HirId::make_owner(id.def_id)) - ) + bug!("expected trait item, found {}", self.hir_id_to_string(HirId::make_owner(id))) } } } + pub fn hir_get_fn_output(self, def_id: LocalDefId) -> Option<&'tcx FnRetTy<'tcx>> { + Some(&self.opt_hir_owner_node(def_id)?.fn_decl()?.output) + } + #[track_caller] - pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> { - match self.tcx.hir_node_by_def_id(id) { + pub fn hir_expect_opaque_ty(self, id: LocalDefId) -> &'tcx OpaqueTy<'tcx> { + match self.hir_node_by_def_id(id) { Node::OpaqueTy(opaq) => opaq, _ => { bug!( "expected opaque type definition, found {}", - self.node_to_string(self.tcx.local_def_id_to_hir_id(id)) + self.hir_id_to_string(self.local_def_id_to_hir_id(id)) ) } } } - pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> { - match self.tcx.hir_node(id) { + pub fn hir_expect_expr(self, id: HirId) -> &'tcx Expr<'tcx> { + match self.hir_node(id) { Node::Expr(expr) => expr, - _ => bug!("expected expr, found {}", self.node_to_string(id)), + _ => bug!("expected expr, found {}", self.hir_id_to_string(id)), } } - pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { - self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() + pub fn hir_opt_delegation_sig_id(self, def_id: LocalDefId) -> Option { + self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id() } #[inline] - fn opt_ident(self, id: HirId) -> Option { - match self.tcx.hir_node(id) { + fn hir_opt_ident(self, id: HirId) -> Option { + match self.hir_node(id) { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::span`. - Node::Ctor(..) => match self.tcx.parent_hir_node(id) { + Node::Ctor(..) => match self.parent_hir_node(id) { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -781,30 +855,32 @@ impl<'hir> Map<'hir> { } #[inline] - pub(super) fn opt_ident_span(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.span) + pub(super) fn hir_opt_ident_span(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.span) } #[inline] - pub fn ident(self, id: HirId) -> Ident { - self.opt_ident(id).unwrap() + pub fn hir_ident(self, id: HirId) -> Ident { + self.hir_opt_ident(id).unwrap() } #[inline] - pub fn opt_name(self, id: HirId) -> Option { - self.opt_ident(id).map(|ident| ident.name) + pub fn hir_opt_name(self, id: HirId) -> Option { + self.hir_opt_ident(id).map(|ident| ident.name) } - pub fn name(self, id: HirId) -> Symbol { - self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.node_to_string(id))) + pub fn hir_name(self, id: HirId) -> Symbol { + self.hir_opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.hir_id_to_string(id))) } /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. - pub fn attrs(self, id: HirId) -> &'hir [Attribute] { - self.tcx.hir_attrs(id.owner).get(id.local_id) + pub fn hir_attrs(self, id: HirId) -> &'tcx [Attribute] { + self.hir_attr_map(id.owner).get(id.local_id) } +} +impl<'hir> Map<'hir> { /// Gets the span of the definition of the specified HIR node. /// This is used by `tcx.def_span`. pub fn span(self, hir_id: HirId) -> Span { @@ -977,12 +1053,6 @@ impl<'hir> Map<'hir> { } } - /// Get a representation of this `id` for debugging purposes. - /// NOTE: Do NOT use this in diagnostics! - pub fn node_to_string(self, id: HirId) -> String { - hir_id_to_string(self, id) - } - /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { @@ -1147,102 +1217,6 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { upstream_crates } -fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); - - let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); - let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); - - match map.tcx.hir_node(id) { - Node::Item(item) => { - let item_str = match item.kind { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", - ItemKind::Static(..) => "static", - ItemKind::Const(..) => "const", - ItemKind::Fn { .. } => "fn", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "mod", - ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::GlobalAsm { .. } => "global asm", - ItemKind::TyAlias(..) => "ty", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl { .. } => "impl", - }; - format!("{id} ({item_str} {})", path_str(item.owner_id.def_id)) - } - Node::ForeignItem(item) => { - format!("{id} (foreign item {})", path_str(item.owner_id.def_id)) - } - Node::ImplItem(ii) => { - let kind = match ii.kind { - ImplItemKind::Const(..) => "associated constant", - ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "method", - }, - ImplItemKind::Type(_) => "associated type", - }; - format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id)) - } - Node::TraitItem(ti) => { - let kind = match ti.kind { - TraitItemKind::Const(..) => "associated constant", - TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self { - ImplicitSelfKind::None => "associated function", - _ => "trait method", - }, - TraitItemKind::Type(..) => "associated type", - }; - - format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id)) - } - Node::Variant(variant) => { - format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id)) - } - Node::Field(field) => { - format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id)) - } - Node::AnonConst(_) => node_str("const"), - Node::ConstBlock(_) => node_str("const"), - Node::ConstArg(_) => node_str("const"), - Node::Expr(_) => node_str("expr"), - Node::ExprField(_) => node_str("expr field"), - Node::Stmt(_) => node_str("stmt"), - Node::PathSegment(_) => node_str("path segment"), - Node::Ty(_) => node_str("type"), - Node::AssocItemConstraint(_) => node_str("assoc item constraint"), - Node::TraitRef(_) => node_str("trait ref"), - Node::OpaqueTy(_) => node_str("opaque type"), - Node::Pat(_) => node_str("pat"), - Node::TyPat(_) => node_str("pat ty"), - Node::PatField(_) => node_str("pattern field"), - Node::PatExpr(_) => node_str("pattern literal"), - Node::Param(_) => node_str("param"), - Node::Arm(_) => node_str("arm"), - Node::Block(_) => node_str("block"), - Node::Infer(_) => node_str("infer"), - Node::LetStmt(_) => node_str("local"), - Node::Ctor(ctor) => format!( - "{id} (ctor {})", - ctor.ctor_def_id().map_or("".into(), |def_id| path_str(def_id)), - ), - Node::Lifetime(_) => node_str("lifetime"), - Node::GenericParam(param) => { - format!("{id} (generic_param {})", path_str(param.def_id)) - } - Node::Crate(..) => String::from("(root_crate)"), - Node::WherePredicate(_) => node_str("where predicate"), - Node::Synthetic => unreachable!(), - Node::Err(_) => node_str("error"), - Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), - } -} - pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { let mut collector = ItemCollector::new(tcx, false); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 6071a58367ed1..68b9a4f56b96d 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -202,13 +202,13 @@ pub fn provide(providers: &mut Providers) { } }) }; - providers.hir_attrs = |tcx, id| { + providers.hir_attr_map = |tcx, id| { tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs) }; providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id)); providers.def_ident_span = |tcx, def_id| { let hir_id = tcx.local_def_id_to_hir_id(def_id); - tcx.hir().opt_ident_span(hir_id) + tcx.hir_opt_ident_span(hir_id) }; providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 2675b7e0fc512..effedf854e473 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -452,12 +452,7 @@ impl<'tcx> TyCtxt<'tcx> { } let id = self.alloc_map.reserve(); debug!("creating alloc {:?} with id {id:?}", alloc_salt.0); - let had_previous = self - .alloc_map - .to_alloc - .lock_shard_by_value(&id) - .insert(id, alloc_salt.0.clone()) - .is_some(); + let had_previous = self.alloc_map.to_alloc.insert(id, alloc_salt.0.clone()).is_some(); // We just reserved, so should always be unique. assert!(!had_previous); dedup.insert(alloc_salt, id); @@ -510,7 +505,7 @@ impl<'tcx> TyCtxt<'tcx> { /// local dangling pointers and allocations in constants/statics. #[inline] pub fn try_get_global_alloc(self, id: AllocId) -> Option> { - self.alloc_map.to_alloc.lock_shard_by_value(&id).get(&id).cloned() + self.alloc_map.to_alloc.get(&id) } #[inline] @@ -529,9 +524,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to /// call this function twice, even with the same `Allocation` will ICE the compiler. pub fn set_alloc_id_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) { - if let Some(old) = - self.alloc_map.to_alloc.lock_shard_by_value(&id).insert(id, GlobalAlloc::Memory(mem)) - { + if let Some(old) = self.alloc_map.to_alloc.insert(id, GlobalAlloc::Memory(mem)) { bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); } } @@ -539,11 +532,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Freezes an `AllocId` created with `reserve` by pointing it at a static item. Trying to /// call this function twice, even with the same `DefId` will ICE the compiler. pub fn set_nested_alloc_id_static(self, id: AllocId, def_id: LocalDefId) { - if let Some(old) = self - .alloc_map - .to_alloc - .lock_shard_by_value(&id) - .insert(id, GlobalAlloc::Static(def_id.to_def_id())) + if let Some(old) = + self.alloc_map.to_alloc.insert(id, GlobalAlloc::Static(def_id.to_def_id())) { bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}"); } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index f880b1364c2cd..007e8d3a245ce 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1200,7 +1200,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { @@ -1221,7 +1221,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { && let Some(upvars) = tcx.upvars_mentioned(def_id) { for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir().name(var_id); + let var_name = tcx.hir_name(var_id); struct_fmt.field(var_name.as_str(), place); } } else { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c8708857565cd..94a5a3769a322 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -25,7 +25,7 @@ use rustc_hir::def_id::{ CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet, LocalModDefId, }; use rustc_hir::lang_items::{LangItem, LanguageItems}; -use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, TraitCandidate}; +use rustc_hir::{Crate, ItemLocalId, ItemLocalMap, PreciseCapturingArgKind, TraitCandidate}; use rustc_index::IndexVec; use rustc_lint_defs::LintId; use rustc_macros::rustc_queries; @@ -198,7 +198,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { + query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } feedable } @@ -1424,7 +1424,7 @@ rustc_queries! { } /// Gets the rendered precise capturing args for an opaque for use in rustdoc. - query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [Symbol]> { + query rendered_precise_capturing_args(def_id: DefId) -> Option<&'tcx [PreciseCapturingArgKind]> { desc { |tcx| "rendering precise capturing args for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 9ce5373b03118..8e54a9d487d92 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -72,7 +72,7 @@ impl OverlapMode { .as_local() .into_iter() .flat_map(|local_def_id| { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(local_def_id)) + tcx.hir_attrs(tcx.local_def_id_to_hir_id(local_def_id)) }) .find(|attr| attr.has_name(sym::rustc_strict_coherence)) .map(|attr| attr.span()); diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 3585f28b4a550..c1dc6a894cae5 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -53,8 +53,6 @@ bitflags::bitflags! { const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. const IS_UNSAFE_CELL = 1 << 9; - /// Indicates whether the type is anonymous. - const IS_ANONYMOUS = 1 << 10; } } rustc_data_structures::external_bitflags_debug! { AdtFlags } @@ -402,12 +400,6 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_MANUALLY_DROP) } - /// Returns `true` if this is an anonymous adt - #[inline] - pub fn is_anonymous(self) -> bool { - self.flags().contains(AdtFlags::IS_ANONYMOUS) - } - /// Returns `true` if this type has a destructor. pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 5d9b1ddfa38ea..703b6ce92471f 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -296,7 +296,7 @@ pub struct CaptureInfo { pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String { let mut curr_string: String = match place.base { - HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(), + HirPlaceBase::Upvar(upvar_id) => tcx.hir_name(upvar_id.var_path.hir_id).to_string(), _ => bug!("Capture_information should only contain upvars"), }; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index edba2a2530f68..a2472157d0e8b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1299,7 +1299,7 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { ), bodies, }))); - self.feed_owner_id().hir_attrs(attrs); + self.feed_owner_id().hir_attr_map(attrs); } } @@ -2214,7 +2214,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the origin of the opaque type `def_id`. #[instrument(skip(self), level = "trace", ret)] pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin { - self.hir().expect_opaque_ty(def_id).origin + self.hir_expect_opaque_ty(def_id).origin } pub fn finish(self) { @@ -2336,8 +2336,8 @@ macro_rules! sty_debug_print { $(let mut $variant = total;)* for shard in tcx.interners.type_.lock_shards() { - let types = shard.keys(); - for &InternedInSet(t) in types { + let types = shard.iter(); + for &(InternedInSet(t), ()) in types { let variant = match t.internee { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Str | ty::Never => continue, @@ -3118,9 +3118,11 @@ impl<'tcx> TyCtxt<'tcx> { pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( - &self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| { - bug!("No bound vars found for {}", self.hir().node_to_string(id)) - }), + &self + .late_bound_vars_map(id.owner) + .get(&id.local_id) + .cloned() + .unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))), ) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c5509c0a6087e..ad9d32fd6c152 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1151,7 +1151,7 @@ pub struct VariantDef { /// `DefId` that identifies the variant's constructor. /// If this variant is a struct variant, then this is `None`. pub ctor: Option<(CtorKind, DefId)>, - /// Variant or struct name, maybe empty for anonymous adt (struct or union). + /// Variant or struct name. pub name: Symbol, /// Discriminant of this variant. pub discr: VariantDiscr, @@ -1696,7 +1696,7 @@ impl<'tcx> TyCtxt<'tcx> { // FIXME(@lcnr): Remove this function. pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] { if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)) + self.hir_attrs(self.local_def_id_to_hir_id(did)) } else { self.attrs_for_def(did) } @@ -1720,7 +1720,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let did: DefId = did.into(); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter() + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter() } else { self.attrs_for_def(did).iter() } @@ -1764,7 +1764,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> impl Iterator { let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr); if let Some(did) = did.as_local() { - self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) + self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) } else { self.attrs_for_def(did).iter().filter(filter_fn) } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 71fc38cb7edb4..19e2b57456327 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -3,6 +3,7 @@ use std::hash::Hash; use rustc_data_structures::unord::UnordMap; use rustc_hir::def_id::DefIndex; use rustc_index::{Idx, IndexVec}; +use rustc_span::Symbol; use crate::ty; @@ -96,6 +97,7 @@ trivially_parameterized_over_tcx! { rustc_hir::def_id::DefIndex, rustc_hir::definitions::DefKey, rustc_hir::OpaqueTyOrigin, + rustc_hir::PreciseCapturingArgKind, rustc_index::bit_set::DenseBitSet, rustc_index::bit_set::FiniteBitSet, rustc_session::cstore::ForeignModule, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6c62c04f42e4c..f1d03d0a6594b 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -50,7 +50,7 @@ impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> { impl fmt::Debug for ty::UpvarId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id)); + let name = ty::tls::with(|tcx| tcx.hir_name(self.var_path.hir_id)); write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id) } } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 7d9c23c05f950..06054e22e7601 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -310,7 +310,7 @@ impl<'tcx> TypeckResults<'tcx> { pub fn node_type(&self, id: HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { - bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id))) + bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id))) }) } @@ -554,7 +554,7 @@ fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { ty::tls::with(|tcx| { bug!( "node {} cannot be placed in TypeckResults with hir_owner {:?}", - tcx.hir().node_to_string(hir_id), + tcx.hir_id_to_string(hir_id), hir_owner ) }); diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index f9fa750e750b3..2909dea98b747 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -485,7 +485,7 @@ fn construct_fn<'tcx>( }; if let Some(custom_mir_attr) = - tcx.hir().attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) + tcx.hir_attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir) { return custom::build_custom_mir( tcx, @@ -741,7 +741,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { coroutine: Option>>, ) -> Builder<'a, 'tcx> { let tcx = infcx.tcx; - let attrs = tcx.hir().attrs(hir_id); + let attrs = tcx.hir_attrs(hir_id); // Some functions always have overflow checks enabled, // however, they may not get codegen'd, depending on // the settings for the crate they are codegened in. diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 8156123949121..27ff01b48034b 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -942,14 +942,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { assert_eq!(orig_id.owner, self.hir_id.owner); let mut id = orig_id; - let hir = self.tcx.hir(); loop { if id == self.hir_id { // This is a moderately common case, mostly hit for previously unseen nodes. break; } - if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { + if self.tcx.hir_attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { // This is a rare case. It's for a node path that doesn't reach the root due to an // intervening lint level attribute. This result doesn't get cached. return id; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index e46e8c9871a5a..b8af77245f25d 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1041,7 +1041,7 @@ impl<'tcx> ThirBuildCx<'tcx> { "Should have already errored about late bound consts: {def_id:?}" ); }; - let name = self.tcx.hir().name(hir_id); + let name = self.tcx.hir_name(hir_id); let param = ty::ParamConst::new(index, name); ExprKind::ConstParam { param, def_id } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 2e069cae4269f..1e84f4aada12f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -73,7 +73,6 @@ struct ThirBuildCx<'tcx> { impl<'tcx> ThirBuildCx<'tcx> { fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { let typeck_results = tcx.typeck(def); - let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); let body_type = match tcx.hir_body_owner_kind(def) { @@ -111,8 +110,8 @@ impl<'tcx> ThirBuildCx<'tcx> { typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, body_owner: def.to_def_id(), - apply_adjustments: hir - .attrs(hir_id) + apply_adjustments: tcx + .hir_attrs(hir_id) .iter() .all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir), } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index dadd1e8546117..cbd29ba837ef6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1043,7 +1043,7 @@ fn find_fallback_pattern_typo<'tcx>( for item in cx.tcx.hir_crate_items(()).free_items() { if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { // Look for consts being re-exported. - let item = cx.tcx.hir().expect_item(item.owner_id.def_id); + let item = cx.tcx.hir_expect_item(item.owner_id.def_id); let use_name = item.ident.name; let hir::ItemKind::Use(path, _) = item.kind else { continue; diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index b0bbec489471d..e48ee71c858c4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -271,12 +271,39 @@ where /// and will need to clearly document it in the rustc-dev-guide before /// stabilization. pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind { - match (self.current_goal_kind, source) { - (_, GoalSource::NormalizeGoal(step_kind)) => step_kind, - (CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => { - PathKind::Coinductive + match source { + // We treat these goals as unknown for now. It is likely that most miscellaneous + // nested goals will be converted to an inductive variant in the future. + // + // Having unknown cycles is always the safer option, as changing that to either + // succeed or hard error is backwards compatible. If we incorrectly treat a cycle + // as inductive even though it should not be, it may be unsound during coherence and + // fixing it may cause inference breakage or introduce ambiguity. + GoalSource::Misc => PathKind::Unknown, + GoalSource::NormalizeGoal(path_kind) => path_kind, + GoalSource::ImplWhereBound => { + // We currently only consider a cycle coinductive if it steps + // into a where-clause of a coinductive trait. + // + // We probably want to make all traits coinductive in the future, + // so we treat cycles involving their where-clauses as ambiguous. + if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind { + PathKind::Coinductive + } else { + PathKind::Unknown + } } - _ => PathKind::Inductive, + // Relating types is always unproductive. If we were to map proof trees to + // corecursive functions as explained in #136824, relating types never + // introduces a constructor which could cause the recursion to be guarded. + GoalSource::TypeRelating => PathKind::Inductive, + // Instantiating a higher ranked goal can never cause the recursion to be + // guarded and is therefore unproductive. + GoalSource::InstantiateHigherRanked => PathKind::Inductive, + // These goal sources are likely unproductive and can be changed to + // `PathKind::Inductive`. Keeping them as unknown until we're confident + // about this and have an example where it is necessary. + GoalSource::AliasBoundConstCondition | GoalSource::AliasWellFormed => PathKind::Unknown, } } @@ -606,7 +633,7 @@ where let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw( GoalEvaluationKind::Nested, - GoalSource::Misc, + GoalSource::TypeRelating, unconstrained_goal, )?; // Add the nested goals from normalization to our own nested goals. @@ -683,7 +710,7 @@ where pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal>) { goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new( self, - GoalSource::Misc, + GoalSource::TypeRelating, goal.param_env, )); self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal); @@ -939,7 +966,15 @@ where rhs: T, ) -> Result<(), NoSolution> { let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; - self.add_goals(GoalSource::Misc, goals); + if cfg!(debug_assertions) { + for g in goals.iter() { + match g.predicate.kind().skip_binder() { + ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => {} + p => unreachable!("unexpected nested goal in `relate`: {p:?}"), + } + } + } + self.add_goals(GoalSource::TypeRelating, goals); Ok(()) } diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs index 1607fbb1b6a7b..6a8e0790f7cb4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs +++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs @@ -421,7 +421,7 @@ impl, I: Interner> ProofTreeBuilder { self.add_goal( delegate, max_input_universe, - GoalSource::Misc, + GoalSource::TypeRelating, goal.with(delegate.cx(), goal.predicate), ); } diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index 1fa35b60304cf..199f0c7512e1b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -313,7 +313,9 @@ where ty::AliasRelationDirection::Equate, ), ); - self.add_goal(GoalSource::Misc, alias_relate_goal); + // We normalize the self type to be able to relate it with + // types from candidates. + self.add_goal(GoalSource::TypeRelating, alias_relate_goal); self.try_evaluate_added_goals()?; Ok(self.resolve_vars_if_possible(normalized_term)) } else { diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals.rs index d945288007174..944d5f0e042d7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals.rs @@ -24,7 +24,8 @@ where ty::AliasRelationDirection::Equate, ), ); - self.add_goal(GoalSource::Misc, goal); + // A projection goal holds if the alias is equal to the expected term. + self.add_goal(GoalSource::TypeRelating, goal); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index 67eb442d2cce7..eba496fa22659 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,9 +1,9 @@ use std::convert::Infallible; use std::marker::PhantomData; -use rustc_type_ir::Interner; use rustc_type_ir::search_graph::{self, PathKind}; -use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult}; +use rustc_type_ir::solve::{CanonicalInput, Certainty, NoSolution, QueryResult}; +use rustc_type_ir::{Interner, TypingMode}; use super::inspect::ProofTreeBuilder; use super::{FIXPOINT_STEP_LIMIT, has_no_inference_or_external_constraints}; @@ -47,7 +47,24 @@ where ) -> QueryResult { match kind { PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes), - PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)), + PathKind::Unknown => response_no_constraints(cx, input, Certainty::overflow(false)), + // Even though we know these cycles to be unproductive, we still return + // overflow during coherence. This is both as we are not 100% confident in + // the implementation yet and any incorrect errors would be unsound there. + // The affected cases are also fairly artificial and not necessarily desirable + // so keeping this as ambiguity is fine for now. + // + // See `tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs` for an + // example where this would matter. We likely should change these cycles to `NoSolution` + // even in coherence once this is a bit more settled. + PathKind::Inductive => match input.typing_mode { + TypingMode::Coherence => { + response_no_constraints(cx, input, Certainty::overflow(false)) + } + TypingMode::Analysis { .. } + | TypingMode::PostBorrowckAnalysis { .. } + | TypingMode::PostAnalysis => Err(NoSolution), + }, } } @@ -57,12 +74,7 @@ where input: CanonicalInput, result: QueryResult, ) -> bool { - match kind { - PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result, - PathKind::Inductive => { - response_no_constraints(cx, input, Certainty::overflow(false)) == result - } - } + Self::initial_provisional_result(cx, kind, input) == result } fn on_stack_overflow( diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index bb227a58cf19d..716ababb00802 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2107,7 +2107,7 @@ impl<'a> Parser<'a> { ast::GenericBound::Trait(poly) => Some(poly), _ => None, }) - .last() + .next_back() { err.span_suggestion_verbose( poly.span.shrink_to_hi(), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c6ae2c0fb9bfd..ece5a53aaa9c4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -52,7 +52,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) hir::ImplItemKind::Const(..) => Target::AssocConst, hir::ImplItemKind::Fn(..) => { let parent_def_id = tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let containing_item = tcx.hir().expect_item(parent_def_id); + let containing_item = tcx.hir_expect_item(parent_def_id); let containing_impl_is_for_trait = match &containing_item.kind { hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), @@ -114,7 +114,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut doc_aliases = FxHashMap::default(); let mut specified_inline = None; let mut seen = FxHashMap::default(); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); for attr in attrs { match attr { Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => { @@ -899,7 +899,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Some(location) = match target { Target::AssocTy => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); if Target::from_item(containing_item) == Target::Impl { Some("type alias in implementation block") } else { @@ -908,7 +908,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Target::AssocConst => { let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; - let containing_item = self.tcx.hir().expect_item(parent_def_id); + let containing_item = self.tcx.hir_expect_item(parent_def_id); // We can't link to trait impl's consts. let err = "associated constant in trait implementation block"; match containing_item.kind { @@ -952,7 +952,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location }); return; } - let item_name = self.tcx.hir().name(hir_id); + let item_name = self.tcx.hir_name(hir_id); if item_name == doc_alias { tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str }); return; @@ -1481,7 +1481,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // `#[must_use]` can be applied to a trait method definition with a default body if let Target::Method(MethodKind::Trait { body: true }) = target && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id - && let containing_item = self.tcx.hir().expect_item(parent_def_id) + && let containing_item = self.tcx.hir_expect_item(parent_def_id) && let hir::ItemKind::Trait(..) = containing_item.kind { return; @@ -2572,7 +2572,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match (target, force_inline_attr) { (Target::Closure, None) => { let is_coro = matches!( - self.tcx.hir().expect_expr(hir_id).kind, + self.tcx.hir_expect_expr(hir_id).kind, hir::ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Coroutine(..) | hir::ClosureKind::CoroutineClosure(..), @@ -2644,8 +2644,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr]; let spans = self .tcx - .hir() - .attrs(where_predicate.hir_id) + .hir_attrs(where_predicate.hir_id) .iter() .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym))) .map(|attr| attr.span()) @@ -2814,7 +2813,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { } fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) { - let attrs = tcx.hir().attrs(item.hir_id()); + let attrs = tcx.hir_attrs(item.hir_id()); for attr in attrs { if attr.has_name(sym::inline) { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 7a14a7a5db299..7029c60c3439b 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -361,7 +361,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) && let TyKind::Path(hir::QPath::Resolved(_, path)) = - self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind + self.tcx.hir_expect_item(local_impl_of).expect_impl().self_ty.kind && let Res::Def(def_kind, did) = path.res { match def_kind { @@ -424,7 +424,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) { if let Some(local_def_id) = impl_def_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_def_id).kind + self.tcx.hir_expect_item(local_def_id).kind { // skip items // mark dependent traits live @@ -448,7 +448,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for impl_id in self.tcx.all_impls(trait_id) { if let Some(local_impl_id) = impl_id.as_local() && let ItemKind::Impl(impl_ref) = - self.tcx.hir().expect_item(local_impl_id).kind + self.tcx.hir_expect_item(local_impl_id).kind { if !matches!(trait_item.kind, hir::TraitItemKind::Type(..)) && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty) diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 323b414cca04c..e13d94c1031ac 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -19,7 +19,7 @@ use rustc_span::{Symbol, sym}; use crate::errors::DuplicateDiagnosticItemInCrate; fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { - let attrs = tcx.hir().attrs(owner.into()); + let attrs = tcx.hir_attrs(owner.into()); if let Some(name) = extract(attrs) { // insert into our table collect_item(tcx, diagnostic_items, name, owner.to_def_id()); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 25e679a84601e..d2729876ebbb4 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -31,7 +31,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } // If the user wants no main function at all, then stop here. - if attr::contains_name(tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) { + if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) { return None; } @@ -45,7 +45,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> { } fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option { - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); attr::find_by_name(attrs, sym).map(|attr| attr.span()) } @@ -61,7 +61,7 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) { let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID); - let attrs = ctxt.tcx.hir().attrs(id.hir_id()); + let attrs = ctxt.tcx.hir_attrs(id.hir_id()); let entry_point_type = rustc_ast::entry::entry_point_type( attrs, at_root, diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 509c2f5477524..84b92d49f24c2 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -60,19 +60,18 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> { .expect("owning item has no entry"); if max != self.hir_ids_seen.len() - 1 { - let hir = self.tcx.hir(); let pretty_owner = self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose(); let missing_items: Vec<_> = (0..=max as u32) .map(|i| ItemLocalId::from_u32(i)) .filter(|&local_id| !self.hir_ids_seen.contains(local_id)) - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); let seen_items: Vec<_> = self .hir_ids_seen .iter() - .map(|local_id| hir.node_to_string(HirId { owner, local_id })) + .map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id })) .collect(); self.error(|| { @@ -137,7 +136,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { self.error(|| { format!( "HirIdValidator: The recorded owner of {} is {} instead of {}", - self.tcx.hir().node_to_string(hir_id), + self.tcx.hir_id_to_string(hir_id), self.tcx.hir_def_path(hir_id.owner.def_id).to_string_no_crate_verbose(), self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose() ) diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 822804893fe2a..ed70d9ee91f5a 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -157,7 +157,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { - let var_name = tcx.hir().name(var_hir_id); + let var_name = tcx.hir_name(var_hir_id); maps.add_variable(Upvar(var_hir_id, var_name)); } } diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 8e59c0b3251ca..b06f16cc7bd2f 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -222,7 +222,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> { if let Some(break_expr) = opt_expr { let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id { - match self.tcx.hir().expect_expr(loop_id).kind { + match self.tcx.hir_expect_expr(loop_id).kind { hir::ExprKind::Loop(_, label, source, sp) => { (Some(sp), label, Some(source)) } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index fd465717bf766..599a08bac20de 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -291,7 +291,7 @@ impl<'tcx> ReachableContext<'tcx> { _ => { bug!( "found unexpected node kind in worklist: {} ({:?})", - self.tcx.hir().node_to_string(self.tcx.local_def_id_to_hir_id(search_item)), + self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(search_item)), node, ); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 0fcf6a80ec4de..aea4386295f31 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { ) where F: FnOnce(&mut Self), { - let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs); let depr = attr::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span)); @@ -795,7 +795,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { }) => { let features = self.tcx.features(); if features.staged_api() { - let attrs = self.tcx.hir().attrs(item.hir_id()); + let attrs = self.tcx.hir_attrs(item.hir_id()); let stab = attr::find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span)); // FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem @@ -1034,7 +1034,7 @@ fn is_unstable_reexport(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { } // If this is a path that isn't a use, we don't need to do anything special - if !matches!(tcx.hir().expect_item(def_id).kind, ItemKind::Use(..)) { + if !matches!(tcx.hir_expect_item(def_id).kind, ItemKind::Use(..)) { return false; } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5271d03a6f617..3794b23c86a60 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -493,7 +493,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { ) { // Non-opaque macros cannot make other items more accessible than they already are. let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id); - let attrs = self.tcx.hir().attrs(hir_id); + let attrs = self.tcx.hir_attrs(hir_id); if attr::find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x) .unwrap_or(Transparency::fallback(md.macro_rules)) @@ -573,7 +573,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { // have normal hygiene, so we can treat them like other items without type // privacy and mark them reachable. DefKind::Macro(_) => { - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind { if vis.is_accessible_from(module, self.tcx) { self.update(def_id, macro_ev, Level::Reachable); @@ -597,7 +597,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { DefKind::Struct | DefKind::Union => { // While structs and unions have type privacy, their fields do not. - let item = self.tcx.hir().expect_item(def_id); + let item = self.tcx.hir_expect_item(def_id); if let hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) = item.kind { diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 6ece01c211bac..3109d53cd2caa 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1,5 +1,4 @@ use std::assert_matches::assert_matches; -use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -9,7 +8,7 @@ use std::sync::atomic::{AtomicU32, Ordering}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef}; -use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_data_structures::unord::UnordMap; @@ -619,7 +618,7 @@ impl DepGraphData { if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) { self.current.prev_index_to_index.lock()[prev_index] } else { - self.current.new_node_to_index.lock_shard_by_value(dep_node).get(dep_node).copied() + self.current.new_node_to_index.get(dep_node) } } @@ -1048,7 +1047,7 @@ rustc_index::newtype_index! { /// first, and `data` second. pub(super) struct CurrentDepGraph { encoder: GraphEncoder, - new_node_to_index: Sharded>, + new_node_to_index: ShardedHashMap, prev_index_to_index: Lock>>, /// This is used to verify that fingerprints do not change between the creation of a node @@ -1117,12 +1116,9 @@ impl CurrentDepGraph { profiler, previous, ), - new_node_to_index: Sharded::new(|| { - FxHashMap::with_capacity_and_hasher( - new_node_count_estimate / sharded::shards(), - Default::default(), - ) - }), + new_node_to_index: ShardedHashMap::with_capacity( + new_node_count_estimate / sharded::shards(), + ), prev_index_to_index: Lock::new(IndexVec::from_elem_n(None, prev_graph_node_count)), anon_id_seed, #[cfg(debug_assertions)] @@ -1152,14 +1148,9 @@ impl CurrentDepGraph { edges: EdgesVec, current_fingerprint: Fingerprint, ) -> DepNodeIndex { - let dep_node_index = match self.new_node_to_index.lock_shard_by_value(&key).entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let dep_node_index = self.encoder.send(key, current_fingerprint, edges); - entry.insert(dep_node_index); - dep_node_index - } - }; + let dep_node_index = self + .new_node_to_index + .get_or_insert_with(key, || self.encoder.send(key, current_fingerprint, edges)); #[cfg(debug_assertions)] self.record_edge(dep_node_index, key, current_fingerprint); @@ -1257,7 +1248,7 @@ impl CurrentDepGraph { ) { let node = &prev_graph.index_to_node(prev_index); debug_assert!( - !self.new_node_to_index.lock_shard_by_value(node).contains_key(node), + !self.new_node_to_index.get(node).is_some(), "node from previous graph present in new node collection" ); } @@ -1382,7 +1373,7 @@ fn panic_on_forbidden_read(data: &DepGraphData, dep_node_index: DepN if dep_node.is_none() { // Try to find it among the new nodes for shard in data.current.new_node_to_index.lock_shards() { - if let Some((node, _)) = shard.iter().find(|(_, index)| **index == dep_node_index) { + if let Some((node, _)) = shard.iter().find(|(_, index)| *index == dep_node_index) { dep_node = Some(*node); break; } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index ee984095ad84b..41ebf2d5ac761 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -3,7 +3,6 @@ #![feature(assert_matches)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] -#![feature(hash_raw_entry)] #![feature(let_chains)] #![feature(min_specialization)] #![warn(unreachable_pub)] diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 3b47e7eba0ff8..30b5d7e595491 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -2,8 +2,7 @@ use std::fmt::Debug; use std::hash::Hash; use std::sync::OnceLock; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sharded::{self, Sharded}; +use rustc_data_structures::sharded::ShardedHashMap; pub use rustc_data_structures::vec_cache::VecCache; use rustc_hir::def_id::LOCAL_CRATE; use rustc_index::Idx; @@ -36,7 +35,7 @@ pub trait QueryCache: Sized { /// In-memory cache for queries whose keys aren't suitable for any of the /// more specialized kinds of cache. Backed by a sharded hashmap. pub struct DefaultCache { - cache: Sharded>, + cache: ShardedHashMap, } impl Default for DefaultCache { @@ -55,19 +54,14 @@ where #[inline(always)] fn lookup(&self, key: &K) -> Option<(V, DepNodeIndex)> { - let key_hash = sharded::make_hash(key); - let lock = self.cache.lock_shard_by_hash(key_hash); - let result = lock.raw_entry().from_key_hashed_nocheck(key_hash, key); - - if let Some((_, value)) = result { Some(*value) } else { None } + self.cache.get(key) } #[inline] fn complete(&self, key: K, value: V, index: DepNodeIndex) { - let mut lock = self.cache.lock_shard_by_value(&key); // We may be overwriting another value. This is all right, since the dep-graph // will check that the fingerprint matches. - lock.insert(key, (value, index)); + self.cache.insert(key, (value, index)); } fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) { diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index acd3b75835105..aa1921fc8e784 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -272,7 +272,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { let tcx = tables.tcx; let did = tables[def_id]; let attrs_iter = if let Some(did) = did.as_local() { - tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter() + tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter() } else { tcx.attrs_for_def(did).iter() }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 42d37418fb848..baf2489b2b8b2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::MatchSource::TryDesugar(scrut_hir_id), ) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results @@ -548,7 +548,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) => match source { hir::MatchSource::TryDesugar(scrut_hir_id) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { - let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { let arg_expr = args.first().expect("try desugaring call w/out arg"); self.typeck_results diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index a6d8eb6add7d0..40958ec1088bc 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -1351,7 +1351,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { && !has_impl_trait(def_id) // FIXME(fn_delegation): In delegation item argument spans are equal to last path // segment. This leads to ICE's when emitting `multipart_suggestion`. - && tcx.hir().opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() + && tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none() { let successor = method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 514615735a507..b39b9c15f2547 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -726,7 +726,7 @@ fn foo(&self) -> Self::T { String::new() } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() { let opaque_local_def_id = def_id.as_local(); let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { - tcx.hir().expect_opaque_ty(opaque_local_def_id) + tcx.hir_expect_opaque_ty(opaque_local_def_id) } else { return false; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index fecb38ab597e4..c7f0a88f951a8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!(" for lifetime parameter `{name}`") } infer::UpvarRegion(ref upvar_id, _) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); + let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id); format!(" for capture of `{var_name}` by closure") } infer::Nll(..) => bug!("NLL variable found in lexical phase"), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index a7e68e6419d84..cdbb92f4c7baa 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -778,8 +778,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let exp_local_id = exp_def_id.as_local()?; match ( - &self.tcx.hir().expect_opaque_ty(last_local_id), - &self.tcx.hir().expect_opaque_ty(exp_local_id), + &self.tcx.hir_expect_opaque_ty(last_local_id), + &self.tcx.hir_expect_opaque_ty(exp_local_id), ) { ( hir::OpaqueTy { bounds: last_bounds, .. }, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ad46a15a5ac6d..4f89f3c2b4992 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -22,7 +22,6 @@ use rustc_hir::{ expr_needs_parens, is_range_literal, }; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::{ @@ -93,7 +92,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { fn get_from_await_ty( &self, visitor: AwaitsVisitor, - hir: map::Map<'tcx>, + tcx: TyCtxt<'tcx>, ty_matches: F, ) -> Option where @@ -102,7 +101,7 @@ impl<'a, 'tcx> CoroutineData<'a, 'tcx> { visitor .awaits .into_iter() - .map(|id| hir.expect_expr(id)) + .map(|id| tcx.hir_expect_expr(id)) .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(await_expr)))) .map(|expr| expr.span) } @@ -2180,8 +2179,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_, G>, obligation: &PredicateObligation<'tcx>, ) -> bool { - let hir = self.tcx.hir(); - // Attempt to detect an async-await error by looking at the obligation causes, looking // for a coroutine to be present. // @@ -2350,7 +2347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut interior_or_upvar_span = None; - let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, hir, ty_matches); + let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, self.tcx, ty_matches); debug!(?from_awaited_ty); // Avoid disclosing internal information to downstream crates. @@ -2428,7 +2425,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Special case the primary error message when send or sync is the trait that was // not implemented. - let hir = self.tcx.hir(); let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) = self.tcx.get_diagnostic_name(trait_pred.def_id()) { @@ -2455,7 +2451,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("future returned by `{name}` is not {trait_name}") })?, @@ -2479,7 +2475,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("async iterator returned by `{name}` is not {trait_name}") })?, @@ -2502,7 +2498,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .parent(coroutine_did) .as_local() .map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id)) .map(|name| { format!("iterator returned by `{name}` is not {trait_name}") })? @@ -3569,7 +3565,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ObligationCauseCode::OpaqueReturnType(expr_info) => { let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { let expr_ty = tcx.short_string(expr_ty, err.long_ty_path()); - let expr = tcx.hir().expect_expr(hir_id); + let expr = tcx.hir_expect_expr(hir_id); (expr_ty, expr) } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() && let body = tcx.hir_body(body_id) diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 4f177df89e230..352ac7c1a4e6f 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -440,7 +440,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { match (child_mode, nested_goal.source()) { ( ChildMode::Trait(_) | ChildMode::Host(_), - GoalSource::Misc | GoalSource::NormalizeGoal(_), + GoalSource::Misc | GoalSource::TypeRelating | GoalSource::NormalizeGoal(_), ) => { continue; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0a54b8468fe3c..e1adabbeaa662 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2231,15 +2231,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - // `Copy` and `Clone` are automatically implemented for an anonymous adt - // if all of its fields are `Copy` and `Clone` - ty::Adt(adt, args) if adt.is_anonymous() => { - // (*) binder moved here - Where(obligation.predicate.rebind( - adt.non_enum_variant().fields.iter().map(|f| f.ty(self.tcx(), args)).collect(), - )) - } - ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => { // Fallback to whatever user-defined impls exist in this case. None diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index c84055f5b84fe..b7684e85d4128 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -21,7 +21,7 @@ pub(crate) fn provide(providers: &mut Providers) { } fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); match item.kind { hir::ItemKind::Trait(.., trait_item_refs) => { // We collect RPITITs for each trait method's return type and create a @@ -96,7 +96,7 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { let id = tcx.local_def_id_to_hir_id(def_id); let parent_def_id = tcx.hir_get_parent_item(id); - let parent_item = tcx.hir().expect_item(parent_def_id.def_id); + let parent_item = tcx.hir_expect_item(parent_def_id.def_id); match parent_item.kind { hir::ItemKind::Impl(impl_) => { if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id) @@ -201,7 +201,7 @@ fn associated_types_for_impl_traits_in_associated_fn( let mut visitor = RPITVisitor { rpits: FxIndexSet::default() }; - if let Some(output) = tcx.hir().get_fn_output(fn_def_id) { + if let Some(output) = tcx.hir_get_fn_output(fn_def_id) { visitor.visit_fn_ret_ty(output); tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 6205578bf7476..aeaa83c77b5f1 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -161,7 +161,7 @@ fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator, def_id: LocalDefId) -> impl Iterator { - let item = tcx.hir().expect_item(def_id); + let item = tcx.hir_expect_item(def_id); if let hir::ItemKind::Impl(impl_) = item.kind { let trait_args = impl_ .of_trait diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 7b2593b96e37f..4adf715792666 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -33,6 +33,3 @@ nightly = [ "rustc_index/nightly", "rustc_ast_ir/nightly", ] - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 18e84db5d686c..9ae8392805779 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -13,6 +13,7 @@ /// behavior as long as the resulting behavior is still correct. use std::cmp::Ordering; use std::collections::BTreeMap; +use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -20,7 +21,7 @@ use std::marker::PhantomData; use derive_where::derive_where; use rustc_index::{Idx, IndexVec}; #[cfg(feature = "nightly")] -use rustc_macros::HashStable_NoContext; +use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use tracing::debug; use crate::data_structures::HashMap; @@ -111,21 +112,35 @@ pub trait Delegate { /// In the initial iteration of a cycle, we do not yet have a provisional /// result. In the case we return an initial provisional result depending /// on the kind of cycle. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum PathKind { - Coinductive, + /// A path consisting of only inductive/unproductive steps. Their initial + /// provisional result is `Err(NoSolution)`. We currently treat them as + /// `PathKind::Unknown` during coherence until we're fully confident in + /// our approach. Inductive, + /// A path which is not be coinductive right now but we may want + /// to change of them to be so in the future. We return an ambiguous + /// result in this case to prevent people from relying on this. + Unknown, + /// A path with at least one coinductive step. Such cycles hold. + Coinductive, } + impl PathKind { /// Returns the path kind when merging `self` with `rest`. /// /// Given an inductive path `self` and a coinductive path `rest`, /// the path `self -> rest` would be coinductive. + /// + /// This operation represents an ordering and would be equivalent + /// to `max(self, rest)`. fn extend(self, rest: PathKind) -> PathKind { - match self { - PathKind::Coinductive => PathKind::Coinductive, - PathKind::Inductive => rest, + match (self, rest) { + (PathKind::Coinductive, _) | (_, PathKind::Coinductive) => PathKind::Coinductive, + (PathKind::Unknown, _) | (_, PathKind::Unknown) => PathKind::Unknown, + (PathKind::Inductive, PathKind::Inductive) => PathKind::Inductive, } } } @@ -159,9 +174,6 @@ impl UsageKind { } } } - fn and_merge(&mut self, other: impl Into) { - *self = self.merge(other); - } } /// For each goal we track whether the paths from this goal @@ -297,7 +309,7 @@ impl CycleHeads { let path_from_entry = match step_kind { PathKind::Coinductive => AllPathsToHeadCoinductive::Yes, - PathKind::Inductive => path_from_entry, + PathKind::Unknown | PathKind::Inductive => path_from_entry, }; self.insert(head, path_from_entry); @@ -305,6 +317,63 @@ impl CycleHeads { } } +bitflags::bitflags! { + /// Tracks how nested goals have been accessed. This is necessary to disable + /// global cache entries if computing them would otherwise result in a cycle or + /// access a provisional cache entry. + #[derive(Debug, Clone, Copy)] + pub struct PathsToNested: u8 { + /// The initial value when adding a goal to its own nested goals. + const EMPTY = 1 << 0; + const INDUCTIVE = 1 << 1; + const UNKNOWN = 1 << 2; + const COINDUCTIVE = 1 << 3; + } +} +impl From for PathsToNested { + fn from(path: PathKind) -> PathsToNested { + match path { + PathKind::Inductive => PathsToNested::INDUCTIVE, + PathKind::Unknown => PathsToNested::UNKNOWN, + PathKind::Coinductive => PathsToNested::COINDUCTIVE, + } + } +} +impl PathsToNested { + /// The implementation of this function is kind of ugly. We check whether + /// there currently exist 'weaker' paths in the set, if so we upgrade these + /// paths to at least `path`. + #[must_use] + fn extend_with(mut self, path: PathKind) -> Self { + match path { + PathKind::Inductive => { + if self.intersects(PathsToNested::EMPTY) { + self.remove(PathsToNested::EMPTY); + self.insert(PathsToNested::INDUCTIVE); + } + } + PathKind::Unknown => { + if self.intersects(PathsToNested::EMPTY | PathsToNested::INDUCTIVE) { + self.remove(PathsToNested::EMPTY | PathsToNested::INDUCTIVE); + self.insert(PathsToNested::UNKNOWN); + } + } + PathKind::Coinductive => { + if self.intersects( + PathsToNested::EMPTY | PathsToNested::INDUCTIVE | PathsToNested::UNKNOWN, + ) { + self.remove( + PathsToNested::EMPTY | PathsToNested::INDUCTIVE | PathsToNested::UNKNOWN, + ); + self.insert(PathsToNested::COINDUCTIVE); + } + } + } + + self + } +} + /// The nested goals of each stack entry and the path from the /// stack entry to that nested goal. /// @@ -322,15 +391,18 @@ impl CycleHeads { /// results from a the cycle BAB depending on the cycle root. #[derive_where(Debug, Default, Clone; X: Cx)] struct NestedGoals { - nested_goals: HashMap, + nested_goals: HashMap, } impl NestedGoals { fn is_empty(&self) -> bool { self.nested_goals.is_empty() } - fn insert(&mut self, input: X::Input, path_from_entry: UsageKind) { - self.nested_goals.entry(input).or_insert(path_from_entry).and_merge(path_from_entry); + fn insert(&mut self, input: X::Input, paths_to_nested: PathsToNested) { + match self.nested_goals.entry(input) { + Entry::Occupied(mut entry) => *entry.get_mut() |= paths_to_nested, + Entry::Vacant(entry) => drop(entry.insert(paths_to_nested)), + } } /// Adds the nested goals of a nested goal, given that the path `step_kind` from this goal @@ -341,18 +413,15 @@ impl NestedGoals { /// the same as for the child. fn extend_from_child(&mut self, step_kind: PathKind, nested_goals: &NestedGoals) { #[allow(rustc::potential_query_instability)] - for (input, path_from_entry) in nested_goals.iter() { - let path_from_entry = match step_kind { - PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), - PathKind::Inductive => path_from_entry, - }; - self.insert(input, path_from_entry); + for (input, paths_to_nested) in nested_goals.iter() { + let paths_to_nested = paths_to_nested.extend_with(step_kind); + self.insert(input, paths_to_nested); } } #[cfg_attr(feature = "nightly", rustc_lint_query_instability)] #[allow(rustc::potential_query_instability)] - fn iter(&self) -> impl Iterator { + fn iter(&self) -> impl Iterator + '_ { self.nested_goals.iter().map(|(i, p)| (*i, *p)) } @@ -490,7 +559,7 @@ impl, X: Cx> SearchGraph { // goals as this change may cause them to now depend on additional // goals, resulting in new cycles. See the dev-guide for examples. if parent_depends_on_cycle { - parent.nested_goals.insert(parent.input, UsageKind::Single(PathKind::Inductive)) + parent.nested_goals.insert(parent.input, PathsToNested::EMPTY); } } } @@ -666,7 +735,7 @@ impl, X: Cx> SearchGraph { // // We must therefore not use the global cache entry for `B` in that case. // See tests/ui/traits/next-solver/cycles/hidden-by-overflow.rs - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); + last.nested_goals.insert(last.input, PathsToNested::EMPTY); } debug!("encountered stack overflow"); @@ -749,16 +818,11 @@ impl, X: Cx> SearchGraph { // We now care about the path from the next highest cycle head to the // provisional cache entry. - match path_from_head { - PathKind::Coinductive => {} - PathKind::Inductive => { - *path_from_head = Self::cycle_path_kind( - &self.stack, - stack_entry.step_kind_from_parent, - head, - ) - } - } + *path_from_head = path_from_head.extend(Self::cycle_path_kind( + &self.stack, + stack_entry.step_kind_from_parent, + head, + )); // Mutate the result of the provisional cache entry in case we did // not reach a fixpoint. *result = mutate_result(input, *result); @@ -858,7 +922,7 @@ impl, X: Cx> SearchGraph { for &ProvisionalCacheEntry { encountered_overflow, ref heads, - path_from_head, + path_from_head: head_to_provisional, result: _, } in entries.iter() { @@ -870,24 +934,19 @@ impl, X: Cx> SearchGraph { // A provisional cache entry only applies if the path from its highest head // matches the path when encountering the goal. + // + // We check if any of the paths taken while computing the global goal + // would end up with an applicable provisional cache entry. let head = heads.highest_cycle_head(); - let full_path = match Self::cycle_path_kind(stack, step_kind_from_parent, head) { - PathKind::Coinductive => UsageKind::Single(PathKind::Coinductive), - PathKind::Inductive => path_from_global_entry, - }; - - match (full_path, path_from_head) { - (UsageKind::Mixed, _) - | (UsageKind::Single(PathKind::Coinductive), PathKind::Coinductive) - | (UsageKind::Single(PathKind::Inductive), PathKind::Inductive) => { - debug!( - ?full_path, - ?path_from_head, - "cache entry not applicable due to matching paths" - ); - return false; - } - _ => debug!(?full_path, ?path_from_head, "paths don't match"), + let head_to_curr = Self::cycle_path_kind(stack, step_kind_from_parent, head); + let full_paths = path_from_global_entry.extend_with(head_to_curr); + if full_paths.contains(head_to_provisional.into()) { + debug!( + ?full_paths, + ?head_to_provisional, + "cache entry not applicable due to matching paths" + ); + return false; } } } @@ -986,8 +1045,8 @@ impl, X: Cx> SearchGraph { let last = &mut self.stack[last_index]; last.reached_depth = last.reached_depth.max(next_index); - last.nested_goals.insert(input, UsageKind::Single(step_kind_from_parent)); - last.nested_goals.insert(last.input, UsageKind::Single(PathKind::Inductive)); + last.nested_goals.insert(input, step_kind_from_parent.into()); + last.nested_goals.insert(last.input, PathsToNested::EMPTY); if last_index != head { last.heads.insert(head, step_kind_from_parent); } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 6f37db1cb85f9..de2e0f2c0ec99 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -58,20 +58,24 @@ impl Goal { /// Why a specific goal has to be proven. /// /// This is necessary as we treat nested goals different depending on -/// their source. This is currently mostly used by proof tree visitors -/// but will be used by cycle handling in the future. +/// their source. This is used to decide whether a cycle is coinductive. +/// See the documentation of `EvalCtxt::step_kind_for_source` for more details +/// about this. +/// +/// It is also used by proof tree visitors, e.g. for diagnostics purposes. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum GoalSource { Misc, - /// We're proving a where-bound of an impl. + /// A nested goal required to prove that types are equal/subtypes. + /// This is always an unproductive step. /// - /// FIXME(-Znext-solver=coinductive): Explain how and why this - /// changes whether cycles are coinductive. + /// This is also used for all `NormalizesTo` goals as we they are used + /// to relate types in `AliasRelate`. + TypeRelating, + /// We're proving a where-bound of an impl. ImplWhereBound, /// Const conditions that need to hold for `~const` alias bounds to hold. - /// - /// FIXME(-Znext-solver=coinductive): Are these even coinductive? AliasBoundConstCondition, /// Instantiating a higher-ranked goal and re-proving it. InstantiateHigherRanked, @@ -79,7 +83,6 @@ pub enum GoalSource { /// This is used in two places: projecting to an opaque whose hidden type /// is already registered in the opaque type storage, and for rigid projections. AliasWellFormed, - /// In case normalizing aliases in nested goals cycles, eagerly normalizing these /// aliases in the context of the parent may incorrectly change the cycle kind. /// Normalizing aliases in goals therefore tracks the original path kind for this diff --git a/library/std/src/net/test.rs b/library/std/src/net/test.rs index a5c3983cd89ec..df48b2f2420c3 100644 --- a/library/std/src/net/test.rs +++ b/library/std/src/net/test.rs @@ -31,3 +31,14 @@ pub fn tsa(a: A) -> Result, String> { Err(e) => Err(e.to_string()), } } + +pub fn compare_ignore_zoneid(a: &SocketAddr, b: &SocketAddr) -> bool { + match (a, b) { + (SocketAddr::V6(a), SocketAddr::V6(b)) => { + a.ip().segments() == b.ip().segments() + && a.flowinfo() == b.flowinfo() + && a.port() == b.port() + } + _ => a == b, + } +} diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs index 1c8c58d187957..91da3135f97c6 100644 --- a/library/std/src/net/udp/tests.rs +++ b/library/std/src/net/udp/tests.rs @@ -1,4 +1,4 @@ -use crate::net::test::{next_test_ip4, next_test_ip6}; +use crate::net::test::{compare_ignore_zoneid, next_test_ip4, next_test_ip6}; use crate::net::*; use crate::sync::mpsc::channel; use crate::thread; @@ -46,7 +46,7 @@ fn socket_smoke_test_ip4() { let (nread, src) = t!(server.recv_from(&mut buf)); assert_eq!(nread, 1); assert_eq!(buf[0], 99); - assert_eq!(src, client_ip); + assert_eq!(compare_ignore_zoneid(&src, &client_ip), true); rx2.recv().unwrap(); }) } @@ -78,7 +78,9 @@ fn udp_clone_smoke() { let _t = thread::spawn(move || { let mut buf = [0, 0]; - assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1)); + let res = sock2.recv_from(&mut buf).unwrap(); + assert_eq!(res.0, 1); + assert_eq!(compare_ignore_zoneid(&res.1, &addr1), true); assert_eq!(buf[0], 1); t!(sock2.send_to(&[2], &addr1)); }); @@ -94,7 +96,9 @@ fn udp_clone_smoke() { }); tx1.send(()).unwrap(); let mut buf = [0, 0]; - assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2)); + let res = sock1.recv_from(&mut buf).unwrap(); + assert_eq!(res.0, 1); + assert_eq!(compare_ignore_zoneid(&res.1, &addr2), true); rx2.recv().unwrap(); }) } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 914971934bfb0..d944bc9c9a2a0 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1454,6 +1454,20 @@ impl File { Ok(()) } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[cfg_attr( + any( + target_os = "android", + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ) + ), + no_sanitize(cfi) + )] pub fn set_times(&self, times: FileTimes) -> io::Result<()> { #[cfg(not(any( target_os = "redox", diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index 2fc33bdfefbf5..a08c7ccec2da3 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -251,6 +251,9 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 25d9e9353320f..be9a7e919905f 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -434,6 +434,9 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, stdio: &ChildPipes, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 11f6998cac118..abe8d3fbf681e 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -188,6 +188,9 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak! { fn pthread_setname_np( diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 0271626380c5f..c0a3044660b7e 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,6 +96,17 @@ impl Timespec { } } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ), + no_sanitize(cfi) + )] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 7ec4787f1eab7..ce3f66a83748b 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -144,6 +144,9 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[no_sanitize(cfi)] unsafe fn $name($($arg_name: $t),*) -> $ret { weak! { fn $name($($t),*) -> $ret } diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 18aa3119842ce..e67bc62a60352 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -454,7 +454,6 @@ tool_check_step!(Rustdoc { path: "src/tools/rustdoc", alt_path: "src/librustdoc" tool_check_step!(Clippy { path: "src/tools/clippy" }); tool_check_step!(Miri { path: "src/tools/miri" }); tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri" }); -tool_check_step!(Rls { path: "src/tools/rls" }); tool_check_step!(Rustfmt { path: "src/tools/rustfmt" }); tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" }); tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" }); diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index fe8c89f7a5394..d3ab215d1b527 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -346,7 +346,6 @@ lint_any!( OptDist, "src/tools/opt-dist", "opt-dist"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; - Rls, "src/tools/rls", "rls"; RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer"; Rustdoc, "src/librustdoc", "clippy"; Rustfmt, "src/tools/rustfmt", "rustfmt"; diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index ec0edeab9968c..c393eb55c6244 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1157,48 +1157,6 @@ impl Step for Cargo { } } -#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] -pub struct Rls { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for Rls { - type Output = Option; - const ONLY_HOSTS: bool = true; - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let default = should_build_extended_tool(run.builder, "rls"); - run.alias("rls").default_condition(default) - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rls { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) -> Option { - let compiler = self.compiler; - let target = self.target; - - let rls = builder.ensure(tool::Rls { compiler, target }); - - let mut tarball = Tarball::new(builder, "rls", &target.triple); - tarball.set_overlay(OverlayKind::Rls); - tarball.is_preview(true); - tarball.add_file(rls.tool_path, "bin", 0o755); - tarball.add_legal_and_readme_to("share/doc/rls"); - Some(tarball.generate()) - } -} - #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] pub struct RustAnalyzer { pub compiler: Compiler, @@ -1528,7 +1486,6 @@ impl Step for Extended { add_component!("rust-json-docs" => JsonDocs { host: target }); add_component!("cargo" => Cargo { compiler, target }); add_component!("rustfmt" => Rustfmt { compiler, target }); - add_component!("rls" => Rls { compiler, target }); add_component!("rust-analyzer" => RustAnalyzer { compiler, target }); add_component!("llvm-components" => LlvmTools { target }); add_component!("clippy" => Clippy { compiler, target }); diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index f25dfaab0f115..e198a8dd6a5be 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -85,9 +85,7 @@ impl FromStr for Profile { "lib" | "library" => Ok(Profile::Library), "compiler" => Ok(Profile::Compiler), "maintainer" | "dist" | "user" => Ok(Profile::Dist), - "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => { - Ok(Profile::Tools) - } + "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" => Ok(Profile::Tools), "none" => Ok(Profile::None), "llvm" | "codegen" => Err("the \"llvm\" and \"codegen\" profiles have been removed,\ use \"compiler\" instead which has the same functionality" diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index e0cf2c121390b..016f09cb2a8ec 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -228,7 +228,6 @@ pub fn prepare_tool_cargo( let mut features = extra_features.to_vec(); if builder.build.config.cargo_native_static { if path.ends_with("cargo") - || path.ends_with("rls") || path.ends_with("clippy") || path.ends_with("miri") || path.ends_with("rustfmt") @@ -1231,7 +1230,6 @@ tool_extended!(CargoMiri { stable: false, add_bins_to_sysroot: ["cargo-miri"] }); -tool_extended!(Rls { path: "src/tools/rls", tool_name: "rls", stable: true }); tool_extended!(Rustfmt { path: "src/tools/rustfmt", tool_name: "rustfmt", diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8e1cecfcd18bc..0b49751f73cb1 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -895,7 +895,6 @@ impl<'a> Builder<'a> { tool::RemoteTestClient, tool::RustInstaller, tool::Cargo, - tool::Rls, tool::RustAnalyzer, tool::RustAnalyzerProcMacroSrv, tool::Rustdoc, @@ -938,7 +937,6 @@ impl<'a> Builder<'a> { clippy::OptDist, clippy::RemoteTestClient, clippy::RemoteTestServer, - clippy::Rls, clippy::RustAnalyzer, clippy::Rustdoc, clippy::Rustfmt, @@ -956,7 +954,6 @@ impl<'a> Builder<'a> { check::Miri, check::CargoMiri, check::MiroptTestTools, - check::Rls, check::Rustfmt, check::RustAnalyzer, check::TestFloatParse, @@ -1071,7 +1068,6 @@ impl<'a> Builder<'a> { dist::Analysis, dist::Src, dist::Cargo, - dist::Rls, dist::RustAnalyzer, dist::Rustfmt, dist::Clippy, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e8820e3a8288d..b062781e68a71 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -261,8 +261,14 @@ fn ci_rustc_if_unchanged_logic() { // Make sure "if-unchanged" logic doesn't try to use CI rustc while there are changes // in compiler and/or library. if config.download_rustc_commit.is_some() { - let has_changes = - config.last_modified_commit(&["compiler", "library"], "download-rustc", true).is_none(); + let mut paths = vec!["compiler"]; + + // Handle library tree the same way as in `Config::download_ci_rustc_commit`. + if build_helper::ci::CiEnv::is_ci() { + paths.push("library"); + } + + let has_changes = config.last_modified_commit(&paths, "download-rustc", true).is_none(); assert!( !has_changes, diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index ac24da9f86b25..09dc9dfbc04ad 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2985,6 +2985,9 @@ impl Config { // these changes to speed up the build process for library developers. This provides consistent // functionality for library developers between `download-rustc=true` and `download-rustc="if-unchanged"` // options. + // + // If you update "library" logic here, update `builder::tests::ci_rustc_if_unchanged_logic` test + // logic accordingly. if !CiEnv::is_ci() { allowed_paths.push(":!library"); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 994ccabf0eb3f..fc4084378389e 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -253,7 +253,7 @@ pub enum Mode { /// Build a tool which uses the locally built rustc and the target std, /// placing the output in the "stageN-tools" directory. This is used for /// anything that needs a fully functional rustc, such as rustdoc, clippy, - /// cargo, rls, rustfmt, miri, etc. + /// cargo, rustfmt, miri, etc. ToolRustc, } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 425ffdccad57f..48d375794b207 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -370,4 +370,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "The rust.description option has moved to build.description and rust.description is now deprecated.", }, + ChangeInfo { + change_id: 126856, + severity: ChangeSeverity::Warning, + summary: "Removed `src/tools/rls` tool as it was deprecated long time ago.", + }, ]; diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 843ea65e83862..f1678bacc9769 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -22,7 +22,6 @@ pub(crate) enum OverlayKind { Clippy, Miri, Rustfmt, - Rls, RustAnalyzer, RustcCodegenCranelift, LlvmBitcodeLinker, @@ -56,7 +55,6 @@ impl OverlayKind { "src/tools/rustfmt/LICENSE-APACHE", "src/tools/rustfmt/LICENSE-MIT", ], - OverlayKind::Rls => &["src/tools/rls/README.md", "LICENSE-APACHE", "LICENSE-MIT"], OverlayKind::RustAnalyzer => &[ "src/tools/rust-analyzer/README.md", "src/tools/rust-analyzer/LICENSE-APACHE", @@ -90,7 +88,6 @@ impl OverlayKind { OverlayKind::Rustfmt => { builder.rustfmt_info.version(builder, &builder.release_num("rustfmt")) } - OverlayKind::Rls => builder.release(&builder.release_num("rls")), OverlayKind::RustAnalyzer => builder .rust_analyzer_info .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")), diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 46343a7b86e8a..c061ec6ebdcee 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -107,6 +107,7 @@ dependencies = [ "build_helper", "clap", "csv", + "glob-match", "insta", "serde", "serde_json", @@ -308,6 +309,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + [[package]] name = "hashbrown" version = "0.15.2" diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index c486f2977a1cb..dde09224afe84 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" anyhow = "1" clap = { version = "4.5", features = ["derive"] } csv = "1" +glob-match = "0.2" serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs new file mode 100644 index 0000000000000..45a188fb234a1 --- /dev/null +++ b/src/ci/citool/src/jobs.rs @@ -0,0 +1,244 @@ +#[cfg(test)] +mod tests; + +use std::collections::BTreeMap; + +use serde_yaml::Value; + +use crate::GitHubContext; + +/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. +#[derive(serde::Deserialize, Debug, Clone)] +pub struct Job { + /// Name of the job, e.g. mingw-check + pub name: String, + /// GitHub runner on which the job should be executed + pub os: String, + pub env: BTreeMap, + /// Should the job be only executed on a specific channel? + #[serde(default)] + pub only_on_channel: Option, + /// Do not cancel the whole workflow if this job fails. + #[serde(default)] + pub continue_on_error: Option, + /// Free additional disk space in the job, by removing unused packages. + #[serde(default)] + pub free_disk: Option, +} + +impl Job { + /// By default, the Docker image of a job is based on its name. + /// However, it can be overridden by its IMAGE environment variable. + pub fn image(&self) -> String { + self.env + .get("IMAGE") + .map(|v| v.as_str().expect("IMAGE value should be a string").to_string()) + .unwrap_or_else(|| self.name.clone()) + } + + fn is_linux(&self) -> bool { + self.os.contains("ubuntu") + } +} + +#[derive(serde::Deserialize, Debug)] +struct JobEnvironments { + #[serde(rename = "pr")] + pr_env: BTreeMap, + #[serde(rename = "try")] + try_env: BTreeMap, + #[serde(rename = "auto")] + auto_env: BTreeMap, +} + +#[derive(serde::Deserialize, Debug)] +pub struct JobDatabase { + #[serde(rename = "pr")] + pub pr_jobs: Vec, + #[serde(rename = "try")] + pub try_jobs: Vec, + #[serde(rename = "auto")] + pub auto_jobs: Vec, + + /// Shared environments for the individual run types. + envs: JobEnvironments, +} + +impl JobDatabase { + /// Find `auto` jobs that correspond to the passed `pattern`. + /// Patterns are matched using the glob syntax. + /// For example `dist-*` matches all jobs starting with `dist-`. + fn find_auto_jobs_by_pattern(&self, pattern: &str) -> Vec { + self.auto_jobs + .iter() + .filter(|j| glob_match::glob_match(pattern, &j.name)) + .cloned() + .collect() + } +} + +pub fn load_job_db(db: &str) -> anyhow::Result { + let mut db: Value = serde_yaml::from_str(&db)?; + + // We need to expand merge keys (<<), because serde_yaml can't deal with them + // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. + db.apply_merge()?; + db.apply_merge()?; + + let db: JobDatabase = serde_yaml::from_value(db)?; + Ok(db) +} + +/// Representation of a job outputted to a GitHub Actions workflow. +#[derive(serde::Serialize, Debug)] +struct GithubActionsJob { + /// The main identifier of the job, used by CI scripts to determine what should be executed. + name: String, + /// Helper label displayed in GitHub Actions interface, containing the job name and a run type + /// prefix (PR/try/auto). + full_name: String, + os: String, + env: BTreeMap, + #[serde(skip_serializing_if = "Option::is_none")] + continue_on_error: Option, + #[serde(skip_serializing_if = "Option::is_none")] + free_disk: Option, +} + +/// Skip CI jobs that are not supposed to be executed on the given `channel`. +fn skip_jobs(jobs: Vec, channel: &str) -> Vec { + jobs.into_iter() + .filter(|job| { + job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel) + }) + .collect() +} + +/// Type of workflow that is being executed on CI +#[derive(Debug)] +pub enum RunType { + /// Workflows that run after a push to a PR branch + PullRequest, + /// Try run started with @bors try + TryJob { job_patterns: Option> }, + /// Merge attempt workflow + AutoJob, +} + +/// Maximum number of custom try jobs that can be requested in a single +/// `@bors try` request. +const MAX_TRY_JOBS_COUNT: usize = 20; + +fn calculate_jobs( + run_type: &RunType, + db: &JobDatabase, + channel: &str, +) -> anyhow::Result> { + let (jobs, prefix, base_env) = match run_type { + RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), + RunType::TryJob { job_patterns } => { + let jobs = if let Some(patterns) = job_patterns { + let mut jobs: Vec = vec![]; + let mut unknown_patterns = vec![]; + for pattern in patterns { + let matched_jobs = db.find_auto_jobs_by_pattern(pattern); + if matched_jobs.is_empty() { + unknown_patterns.push(pattern.clone()); + } else { + for job in matched_jobs { + if !jobs.iter().any(|j| j.name == job.name) { + jobs.push(job); + } + } + } + } + if !unknown_patterns.is_empty() { + return Err(anyhow::anyhow!( + "Patterns `{}` did not match any auto jobs", + unknown_patterns.join(", ") + )); + } + if jobs.len() > MAX_TRY_JOBS_COUNT { + return Err(anyhow::anyhow!( + "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs expanded from {} pattern(s)", + jobs.len(), + patterns.len() + )); + } + jobs + } else { + db.try_jobs.clone() + }; + (jobs, "try", &db.envs.try_env) + } + RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), + }; + let jobs = skip_jobs(jobs, channel); + let jobs = jobs + .into_iter() + .map(|job| { + let mut env: BTreeMap = crate::yaml_map_to_json(base_env); + env.extend(crate::yaml_map_to_json(&job.env)); + let full_name = format!("{prefix} - {}", job.name); + + GithubActionsJob { + name: job.name, + full_name, + os: job.os, + env, + continue_on_error: job.continue_on_error, + free_disk: job.free_disk, + } + }) + .collect(); + + Ok(jobs) +} + +pub fn calculate_job_matrix( + db: JobDatabase, + gh_ctx: GitHubContext, + channel: &str, +) -> anyhow::Result<()> { + let run_type = gh_ctx.get_run_type().ok_or_else(|| { + anyhow::anyhow!("Cannot determine the type of workflow that is being executed") + })?; + eprintln!("Run type: {run_type:?}"); + + let jobs = calculate_jobs(&run_type, &db, channel)?; + if jobs.is_empty() { + return Err(anyhow::anyhow!("Computed job list is empty")); + } + + let run_type = match run_type { + RunType::PullRequest => "pr", + RunType::TryJob { .. } => "try", + RunType::AutoJob => "auto", + }; + + eprintln!("Output"); + eprintln!("jobs={jobs:?}"); + eprintln!("run_type={run_type}"); + println!("jobs={}", serde_json::to_string(&jobs)?); + println!("run_type={run_type}"); + + Ok(()) +} + +pub fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> { + let Some(job) = jobs.iter().find(|j| j.name == name) else { + let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect(); + let mut available_jobs = + available_jobs.iter().map(|j| j.name.to_string()).collect::>(); + available_jobs.sort(); + return Err(anyhow::anyhow!( + "Job {name} not found. The following jobs are available:\n{}", + available_jobs.join(", ") + )); + }; + if !job.is_linux() { + return Err(anyhow::anyhow!("Only Linux jobs can be executed locally")); + } + + Ok(job) +} diff --git a/src/ci/citool/src/jobs/tests.rs b/src/ci/citool/src/jobs/tests.rs new file mode 100644 index 0000000000000..a489656fa5dc7 --- /dev/null +++ b/src/ci/citool/src/jobs/tests.rs @@ -0,0 +1,64 @@ +use crate::jobs::{JobDatabase, load_job_db}; + +#[test] +fn lookup_job_pattern() { + let db = load_job_db( + r#" +envs: + pr: + try: + auto: + +pr: +try: +auto: + - name: dist-a + os: ubuntu + env: {} + - name: dist-a-alt + os: ubuntu + env: {} + - name: dist-b + os: ubuntu + env: {} + - name: dist-b-alt + os: ubuntu + env: {} + - name: test-a + os: ubuntu + env: {} + - name: test-a-alt + os: ubuntu + env: {} + - name: test-i686 + os: ubuntu + env: {} + - name: dist-i686 + os: ubuntu + env: {} + - name: test-msvc-i686-1 + os: ubuntu + env: {} + - name: test-msvc-i686-2 + os: ubuntu + env: {} +"#, + ) + .unwrap(); + check_pattern(&db, "dist-*", &["dist-a", "dist-a-alt", "dist-b", "dist-b-alt", "dist-i686"]); + check_pattern(&db, "*-alt", &["dist-a-alt", "dist-b-alt", "test-a-alt"]); + check_pattern(&db, "dist*-alt", &["dist-a-alt", "dist-b-alt"]); + check_pattern( + &db, + "*i686*", + &["test-i686", "dist-i686", "test-msvc-i686-1", "test-msvc-i686-2"], + ); +} + +#[track_caller] +fn check_pattern(db: &JobDatabase, pattern: &str, expected: &[&str]) { + let jobs = + db.find_auto_jobs_by_pattern(pattern).into_iter().map(|j| j.name).collect::>(); + + assert_eq!(jobs, expected); +} diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index 52e7638d98bdf..cd690ebeb0625 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,5 +1,6 @@ mod cpu_usage; mod datadog; +mod jobs; mod merge_report; mod metrics; mod utils; @@ -10,10 +11,12 @@ use std::process::Command; use anyhow::Context; use clap::Parser; +use jobs::JobDatabase; use serde_yaml::Value; use crate::cpu_usage::load_cpu_usage; use crate::datadog::upload_datadog_metric; +use crate::jobs::RunType; use crate::merge_report::post_merge_report; use crate::metrics::postprocess_metrics; use crate::utils::load_env_var; @@ -22,104 +25,6 @@ const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); -/// Representation of a job loaded from the `src/ci/github-actions/jobs.yml` file. -#[derive(serde::Deserialize, Debug, Clone)] -struct Job { - /// Name of the job, e.g. mingw-check - name: String, - /// GitHub runner on which the job should be executed - os: String, - env: BTreeMap, - /// Should the job be only executed on a specific channel? - #[serde(default)] - only_on_channel: Option, - /// Rest of attributes that will be passed through to GitHub actions - #[serde(flatten)] - extra_keys: BTreeMap, -} - -impl Job { - fn is_linux(&self) -> bool { - self.os.contains("ubuntu") - } - - /// By default, the Docker image of a job is based on its name. - /// However, it can be overridden by its IMAGE environment variable. - fn image(&self) -> String { - self.env - .get("IMAGE") - .map(|v| v.as_str().expect("IMAGE value should be a string").to_string()) - .unwrap_or_else(|| self.name.clone()) - } -} - -#[derive(serde::Deserialize, Debug)] -struct JobEnvironments { - #[serde(rename = "pr")] - pr_env: BTreeMap, - #[serde(rename = "try")] - try_env: BTreeMap, - #[serde(rename = "auto")] - auto_env: BTreeMap, -} - -#[derive(serde::Deserialize, Debug)] -struct JobDatabase { - #[serde(rename = "pr")] - pr_jobs: Vec, - #[serde(rename = "try")] - try_jobs: Vec, - #[serde(rename = "auto")] - auto_jobs: Vec, - - /// Shared environments for the individual run types. - envs: JobEnvironments, -} - -impl JobDatabase { - fn find_auto_job_by_name(&self, name: &str) -> Option { - self.auto_jobs.iter().find(|j| j.name == name).cloned() - } -} - -fn load_job_db(path: &Path) -> anyhow::Result { - let db = utils::read_to_string(path)?; - let mut db: Value = serde_yaml::from_str(&db)?; - - // We need to expand merge keys (<<), because serde_yaml can't deal with them - // `apply_merge` only applies the merge once, so do it a few times to unwrap nested merges. - db.apply_merge()?; - db.apply_merge()?; - - let db: JobDatabase = serde_yaml::from_value(db)?; - Ok(db) -} - -/// Representation of a job outputted to a GitHub Actions workflow. -#[derive(serde::Serialize, Debug)] -struct GithubActionsJob { - /// The main identifier of the job, used by CI scripts to determine what should be executed. - name: String, - /// Helper label displayed in GitHub Actions interface, containing the job name and a run type - /// prefix (PR/try/auto). - full_name: String, - os: String, - env: BTreeMap, - #[serde(flatten)] - extra_keys: BTreeMap, -} - -/// Type of workflow that is being executed on CI -#[derive(Debug)] -enum RunType { - /// Workflows that run after a push to a PR branch - PullRequest, - /// Try run started with @bors try - TryJob { custom_jobs: Option> }, - /// Merge attempt workflow - AutoJob, -} - struct GitHubContext { event_name: String, branch_ref: String, @@ -130,24 +35,31 @@ impl GitHubContext { fn get_run_type(&self) -> Option { match (self.event_name.as_str(), self.branch_ref.as_str()) { ("pull_request", _) => Some(RunType::PullRequest), - ("push", "refs/heads/try-perf") => Some(RunType::TryJob { custom_jobs: None }), + ("push", "refs/heads/try-perf") => Some(RunType::TryJob { job_patterns: None }), ("push", "refs/heads/try" | "refs/heads/automation/bors/try") => { - let custom_jobs = self.get_custom_jobs(); - let custom_jobs = if !custom_jobs.is_empty() { Some(custom_jobs) } else { None }; - Some(RunType::TryJob { custom_jobs }) + let patterns = self.get_try_job_patterns(); + let patterns = if !patterns.is_empty() { Some(patterns) } else { None }; + Some(RunType::TryJob { job_patterns: patterns }) } ("push", "refs/heads/auto") => Some(RunType::AutoJob), _ => None, } } - /// Tries to parse names of specific CI jobs that should be executed in the form of - /// try-job: - /// from the commit message of the passed GitHub context. - fn get_custom_jobs(&self) -> Vec { + /// Tries to parse patterns of CI jobs that should be executed + /// from the commit message of the passed GitHub context + /// + /// They can be specified in the form of + /// try-job: + /// or + /// try-job: `` + /// (to avoid GitHub rendering the glob patterns as Markdown) + fn get_try_job_patterns(&self) -> Vec { if let Some(ref msg) = self.commit_message { msg.lines() .filter_map(|line| line.trim().strip_prefix("try-job: ")) + // Strip backticks if present + .map(|l| l.trim_matches('`')) .map(|l| l.trim().to_string()) .collect() } else { @@ -164,15 +76,6 @@ fn load_github_ctx() -> anyhow::Result { Ok(GitHubContext { event_name, branch_ref: load_env_var("GITHUB_REF")?, commit_message }) } -/// Skip CI jobs that are not supposed to be executed on the given `channel`. -fn skip_jobs(jobs: Vec, channel: &str) -> Vec { - jobs.into_iter() - .filter(|job| { - job.only_on_channel.is_none() || job.only_on_channel.as_deref() == Some(channel) - }) - .collect() -} - fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap { map.into_iter() .map(|(key, value)| { @@ -184,124 +87,13 @@ fn yaml_map_to_json(map: &BTreeMap) -> BTreeMap anyhow::Result> { - let (jobs, prefix, base_env) = match run_type { - RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env), - RunType::TryJob { custom_jobs } => { - let jobs = if let Some(custom_jobs) = custom_jobs { - if custom_jobs.len() > MAX_TRY_JOBS_COUNT { - return Err(anyhow::anyhow!( - "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs", - custom_jobs.len() - )); - } - - let mut jobs = vec![]; - let mut unknown_jobs = vec![]; - for custom_job in custom_jobs { - if let Some(job) = db.find_auto_job_by_name(custom_job) { - jobs.push(job); - } else { - unknown_jobs.push(custom_job.clone()); - } - } - if !unknown_jobs.is_empty() { - return Err(anyhow::anyhow!( - "Custom job(s) `{}` not found in auto jobs", - unknown_jobs.join(", ") - )); - } - jobs - } else { - db.try_jobs.clone() - }; - (jobs, "try", &db.envs.try_env) - } - RunType::AutoJob => (db.auto_jobs.clone(), "auto", &db.envs.auto_env), - }; - let jobs = skip_jobs(jobs, channel); - let jobs = jobs - .into_iter() - .map(|job| { - let mut env: BTreeMap = yaml_map_to_json(base_env); - env.extend(yaml_map_to_json(&job.env)); - let full_name = format!("{prefix} - {}", job.name); - - GithubActionsJob { - name: job.name, - full_name, - os: job.os, - env, - extra_keys: yaml_map_to_json(&job.extra_keys), - } - }) - .collect(); - - Ok(jobs) -} - -fn calculate_job_matrix( - db: JobDatabase, - gh_ctx: GitHubContext, - channel: &str, -) -> anyhow::Result<()> { - let run_type = gh_ctx.get_run_type().ok_or_else(|| { - anyhow::anyhow!("Cannot determine the type of workflow that is being executed") - })?; - eprintln!("Run type: {run_type:?}"); - - let jobs = calculate_jobs(&run_type, &db, channel)?; - if jobs.is_empty() { - return Err(anyhow::anyhow!("Computed job list is empty")); - } - - let run_type = match run_type { - RunType::PullRequest => "pr", - RunType::TryJob { .. } => "try", - RunType::AutoJob => "auto", - }; - - eprintln!("Output"); - eprintln!("jobs={jobs:?}"); - eprintln!("run_type={run_type}"); - println!("jobs={}", serde_json::to_string(&jobs)?); - println!("run_type={run_type}"); - - Ok(()) -} - -fn find_linux_job<'a>(jobs: &'a [Job], name: &str) -> anyhow::Result<&'a Job> { - let Some(job) = jobs.iter().find(|j| j.name == name) else { - let available_jobs: Vec<&Job> = jobs.iter().filter(|j| j.is_linux()).collect(); - let mut available_jobs = - available_jobs.iter().map(|j| j.name.to_string()).collect::>(); - available_jobs.sort(); - return Err(anyhow::anyhow!( - "Job {name} not found. The following jobs are available:\n{}", - available_jobs.join(", ") - )); - }; - if !job.is_linux() { - return Err(anyhow::anyhow!("Only Linux jobs can be executed locally")); - } - - Ok(job) -} - fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> anyhow::Result<()> { let jobs = match job_type { JobType::Auto => &db.auto_jobs, JobType::PR => &db.pr_jobs, }; - let job = find_linux_job(jobs, &name).with_context(|| format!("Cannot find job {name}"))?; + let job = + jobs::find_linux_job(jobs, &name).with_context(|| format!("Cannot find job {name}"))?; let mut custom_env: BTreeMap = BTreeMap::new(); // Replicate src/ci/scripts/setup-environment.sh @@ -385,7 +177,7 @@ enum Args { } #[derive(clap::ValueEnum, Clone)] -enum JobType { +pub enum JobType { /// Merge attempt ("auto") job Auto, /// Pull request job @@ -395,7 +187,10 @@ enum JobType { fn main() -> anyhow::Result<()> { let args = Args::parse(); let default_jobs_file = Path::new(JOBS_YML_PATH); - let load_db = |jobs_path| load_job_db(jobs_path).context("Cannot load jobs.yml"); + let load_db = |jobs_path| { + let db = utils::read_to_string(jobs_path)?; + Ok::<_, anyhow::Error>(jobs::load_job_db(&db).context("Cannot load jobs.yml")?) + }; match args { Args::CalculateJobMatrix { jobs_file } => { @@ -407,7 +202,7 @@ fn main() -> anyhow::Result<()> { .trim() .to_string(); - calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) + jobs::calculate_job_matrix(load_db(jobs_path)?, gh_ctx, &channel) .context("Failed to calculate job matrix")?; } Args::RunJobLocally { job_type, name } => { diff --git a/src/ci/citool/src/merge_report.rs b/src/ci/citool/src/merge_report.rs index 5dd662280f0f3..17e42d49286fe 100644 --- a/src/ci/citool/src/merge_report.rs +++ b/src/ci/citool/src/merge_report.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use anyhow::Context; use build_helper::metrics::{JsonRoot, TestOutcome}; -use crate::JobDatabase; +use crate::jobs::JobDatabase; use crate::metrics::get_test_suites; type Sha = String; diff --git a/src/doc/book b/src/doc/book index 4a01a9182496f..81a976a237f84 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 4a01a9182496f807aaa5f72d93a25ce18bcbe105 +Subproject commit 81a976a237f84b8392c4ce1bd5fd076eb757a2eb diff --git a/src/doc/edition-guide b/src/doc/edition-guide index daa4b763cd848..1e27e5e6d5133 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit daa4b763cd848f986813b5cf8069e1649f7147af +Subproject commit 1e27e5e6d5133ae4612f5cc195c15fc8d51b1c9c diff --git a/src/doc/nomicon b/src/doc/nomicon index 8f5c7322b65d0..b4448fa406a6d 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 8f5c7322b65d079aa5b242eb10d89a98e12471e1 +Subproject commit b4448fa406a6dccde62d1e2f34f70fc51814cdcc diff --git a/src/doc/reference b/src/doc/reference index 615b4cec60c26..dda31c85f2ef2 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 615b4cec60c269cfc105d511c93287620032d5b0 +Subproject commit dda31c85f2ef2e5d2f0f2f643c9231690a30a626 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 66543bbc5b7db..6f69823c28ae8 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 66543bbc5b7dbd4e679092c07ae06ba6c73fd912 +Subproject commit 6f69823c28ae8d929d6c815181c73d3e99ef16d3 diff --git a/src/doc/rustc-dev-guide/src/hir.md b/src/doc/rustc-dev-guide/src/hir.md index 51893d537d750..75f5a9e204528 100644 --- a/src/doc/rustc-dev-guide/src/hir.md +++ b/src/doc/rustc-dev-guide/src/hir.md @@ -139,12 +139,12 @@ defined in the map. By matching on this, you can find out what sort of node the `HirId` referred to and also get a pointer to the data itself. Often, you know what sort of node `n` is – e.g. if you know that `n` must be some HIR expression, you can do -[`tcx.hir().expect_expr(n)`][expect_expr], which will extract and return the +[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the [`&hir::Expr`][Expr], panicking if `n` is not in fact an expression. [find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find [`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html -[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.expect_expr +[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr [Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html Finally, you can use the HIR map to find the parents of nodes, via diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index ae6adb678af14..0c0f750a45d72 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -133,29 +133,37 @@ There are several use-cases for try builds: Again, a working compiler build is needed for this, which can be produced by the [dist-x86_64-linux] CI job. - Run a specific CI job (e.g. Windows tests) on a PR, to quickly test if it - passes the test suite executed by that job. You can select which CI jobs will - be executed in the try build by adding up to 10 lines containing `try-job: - ` to the PR description. All such specified jobs will be executed - in the try build once the `@bors try` command is used on the PR. If no try - jobs are specified in this way, the jobs defined in the `try` section of - [`jobs.yml`] will be executed by default. + passes the test suite executed by that job. + +You can select which CI jobs will +be executed in the try build by adding lines containing `try-job: +` to the PR description. All such specified jobs will be executed +in the try build once the `@bors try` command is used on the PR. If no try +jobs are specified in this way, the jobs defined in the `try` section of +[`jobs.yml`] will be executed by default. + +Each pattern can either be an exact name of a job or a glob pattern that matches multiple jobs, +for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try build. When using +glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering +the pattern as Markdown. > **Using `try-job` PR description directives** > -> 1. Identify which set of try-jobs (max 10) you would like to exercise. You can +> 1. Identify which set of try-jobs you would like to exercise. You can > find the name of the CI jobs in [`jobs.yml`]. > -> 2. Amend PR description to include (usually at the end of the PR description) -> e.g. +> 2. Amend PR description to include a set of patterns (usually at the end +> of the PR description), for example: > > ```text > This PR fixes #123456. > > try-job: x86_64-msvc > try-job: test-various +> try-job: `*-alt` > ``` > -> Each `try-job` directive must be on its own line. +> Each `try-job` pattern must be on its own line. > > 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this > requires the user to either (1) have `try` permissions or (2) be delegated diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index b1d7e5421c1b4..2f86021a4859d 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -72,6 +72,7 @@ - [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md) - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md) - [powerpc64-ibm-aix](platform-support/aix.md) + - [powerpc64le-unknown-linux-gnu](platform-support/powerpc64le-unknown-linux-gnu.md) - [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md) - [riscv32e\*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md) - [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index f78ab151b9c24..486aa1e091cfc 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -96,7 +96,7 @@ target | notes [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) -`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17) +[`powerpc64le-unknown-linux-gnu`](platform-support/powerpc64le-unknown-linux-gnu.md) | PPC64LE Linux (kernel 3.10, glibc 2.17) [`powerpc64le-unknown-linux-musl`](platform-support/powerpc64le-unknown-linux-musl.md) | PPC64LE Linux (kernel 4.19, musl 1.2.3) [`riscv64gc-unknown-linux-gnu`](platform-support/riscv64gc-unknown-linux-gnu.md) | RISC-V Linux (kernel 4.20, glibc 2.29) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) diff --git a/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md new file mode 100644 index 0000000000000..6cb34b2a777a5 --- /dev/null +++ b/src/doc/rustc/src/platform-support/powerpc64le-unknown-linux-gnu.md @@ -0,0 +1,47 @@ +# `powerpc64le-unknown-linux-gnu` + +**Tier: 2** + +Target for 64-bit little endian PowerPC Linux programs + +## Target maintainers + +- David Tenty `daltenty@ibm.com`, https://github.com/daltenty +- Chris Cambly, `ccambly@ca.ibm.com`, https://github.com/gilamn5tr + +## Requirements + +Building the target itself requires a 64-bit little endian PowerPC compiler that is supported by `cc-rs`. + +## Building the target + +The target can be built by enabling it for a `rustc` build. + +```toml +[build] +target = ["powerpc64le-unknown-linux-gnu"] +``` + +Make sure your C compiler is included in `$PATH`, then add it to the `config.toml`: + +```toml +[target.powerpc64le-unknown-linux-gnu] +cc = "powerpc64le-linux-gnu-gcc" +cxx = "powerpc64le-linux-gnu-g++" +ar = "powerpc64le-linux-gnu-ar" +linker = "powerpc64le-linux-gnu-gcc" +``` + +## Building Rust programs + +This target is distributed through `rustup`, and requires no special +configuration. + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Testing + +This target can be tested as normal with `x.py` on a 64-bit little endian +PowerPC host or via QEMU emulation. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 8c6ea00d4890d..e973b89b2375b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -181,7 +181,7 @@ pub(crate) fn try_inline_glob( .filter_map(|child| child.res.opt_def_id()) .filter(|def_id| !cx.tcx.is_doc_hidden(def_id)) .collect(); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let mut items = build_module_items( cx, did, @@ -455,7 +455,7 @@ pub(crate) fn build_impl( } let impl_item = match did.as_local() { - Some(did) => match &tcx.hir().expect_item(did).kind { + Some(did) => match &tcx.hir_expect_item(did).kind { hir::ItemKind::Impl(impl_) => Some(impl_), _ => panic!("`DefID` passed to `build_impl` is not an `impl"), }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 97ff4c2ef4096..0f476c8c9ffd2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -112,7 +112,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.inlined_foreigns.iter().flat_map(|((_, renamed), (res, local_import_id))| { let Some(def_id) = res.opt_def_id() else { return Vec::new() }; let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id)); - let import = cx.tcx.hir().expect_item(*local_import_id); + let import = cx.tcx.hir_expect_item(*local_import_id); match import.kind { hir::ItemKind::Use(path, kind) => { let hir::UsePath { segments, span, .. } = *path; @@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { - let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) } else { // skip everything else @@ -231,7 +231,7 @@ fn clean_generic_bound<'tcx>( GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers) } hir::GenericBound::Use(args, ..) => { - GenericBound::Use(args.iter().map(|arg| arg.name()).collect()) + GenericBound::Use(args.iter().map(|arg| clean_precise_capturing_arg(arg, cx)).collect()) } }) } @@ -286,6 +286,18 @@ fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime { Lifetime(lifetime.ident.name) } +pub(crate) fn clean_precise_capturing_arg( + arg: &hir::PreciseCapturingArg<'_>, + cx: &DocContext<'_>, +) -> PreciseCapturingArg { + match arg { + hir::PreciseCapturingArg::Lifetime(lt) => { + PreciseCapturingArg::Lifetime(clean_lifetime(lt, cx)) + } + hir::PreciseCapturingArg::Param(param) => PreciseCapturingArg::Param(param.ident.name), + } +} + pub(crate) fn clean_const<'tcx>( constant: &hir::ConstArg<'tcx>, _cx: &mut DocContext<'tcx>, @@ -986,7 +998,7 @@ fn clean_proc_macro<'tcx>( kind: MacroKind, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if kind == MacroKind::Derive && let Some(derive_name) = hir_attr_lists(attrs, sym::proc_macro_derive).find_map(|mi| mi.ident()) @@ -1019,7 +1031,7 @@ fn clean_fn_or_proc_macro<'tcx>( name: &mut Symbol, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let macro_kind = attrs.iter().find_map(|a| { if a.has_name(sym::proc_macro) { Some(MacroKind::Bang) @@ -1756,7 +1768,7 @@ fn maybe_expand_private_type_alias<'tcx>( let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id()) && !cx.current_type_aliases.contains_key(&def_id.to_def_id()) { - &cx.tcx.hir().expect_item(def_id).kind + &cx.tcx.hir_expect_item(def_id).kind } else { return None; }; @@ -2364,7 +2376,18 @@ fn clean_middle_opaque_bounds<'tcx>( } if let Some(args) = cx.tcx.rendered_precise_capturing_args(impl_trait_def_id) { - bounds.push(GenericBound::Use(args.to_vec())); + bounds.push(GenericBound::Use( + args.iter() + .map(|arg| match arg { + hir::PreciseCapturingArgKind::Lifetime(lt) => { + PreciseCapturingArg::Lifetime(Lifetime(*lt)) + } + hir::PreciseCapturingArgKind::Param(param) => { + PreciseCapturingArg::Param(*param) + } + }) + .collect(), + )); } ImplTrait(bounds) @@ -2762,7 +2785,7 @@ fn clean_maybe_renamed_item<'tcx>( use hir::ItemKind; let def_id = item.owner_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); + let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id())); cx.with_param_env(def_id, |cx| { let kind = match item.kind { ItemKind::Static(ty, mutability, body_id) => StaticItem(Static { @@ -2937,7 +2960,7 @@ fn clean_extern_crate<'tcx>( let cnum = cx.tcx.extern_mod_stmt_cnum(krate.owner_id.def_id).unwrap_or(LOCAL_CRATE); // this is the ID of the crate itself let crate_def_id = cnum.as_def_id(); - let attrs = cx.tcx.hir().attrs(krate.hir_id()); + let attrs = cx.tcx.hir_attrs(krate.hir_id()); let ty_vis = cx.tcx.visibility(krate.owner_id); let please_inline = ty_vis.is_public() && attrs.iter().any(|a| { @@ -3006,7 +3029,7 @@ fn clean_use_statement_inner<'tcx>( } let visibility = cx.tcx.visibility(import.owner_id); - let attrs = cx.tcx.hir().attrs(import.hir_id()); + let attrs = cx.tcx.hir_attrs(import.hir_id()); let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline); let pub_underscore = visibility.is_public() && name == kw::Underscore; let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9e9cd52883491..228d9108e4eb6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1240,7 +1240,7 @@ pub(crate) enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifiers), Outlives(Lifetime), /// `use<'a, T>` precise-capturing bound syntax - Use(Vec), + Use(Vec), } impl GenericBound { @@ -1304,6 +1304,21 @@ impl Lifetime { } } +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub(crate) enum PreciseCapturingArg { + Lifetime(Lifetime), + Param(Symbol), +} + +impl PreciseCapturingArg { + pub(crate) fn name(self) -> Symbol { + match self { + PreciseCapturingArg::Lifetime(lt) => lt.0, + PreciseCapturingArg::Param(param) => param, + } + } +} + #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub(crate) enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec, bound_params: Vec }, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 88af9a7388cea..f7f0c9766e2f6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -216,7 +216,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); + let crate_attrs = tcx.hir_attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); let enable_per_target_ignores = options.enable_per_target_ignores; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 907e2a3eb2fcd..18ad442d01789 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -95,7 +95,7 @@ impl HirCollector<'_> { sp: Span, nested: F, ) { - let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id)); + let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 8b8439a253527..e93b9eb272a47 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -283,7 +283,7 @@ impl clean::GenericBound { } else { f.write_str("use<")?; } - args.iter().joined(", ", f)?; + args.iter().map(|arg| arg.name()).joined(", ", f)?; if f.alternate() { f.write_str(">") } else { f.write_str(">") } } }) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index edfcc1291b976..4150c5609a97e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */ +/* global addClass, getSettingValue, hasClass, updateLocalStorage */ /* global onEachLazy, removeClass, getVar */ "use strict"; @@ -121,12 +121,9 @@ function getNakedUrl() { * doesn't have a parent node. * * @param {HTMLElement} newNode - * @param {HTMLElement} referenceNode + * @param {HTMLElement & { parentNode: HTMLElement }} referenceNode */ function insertAfter(newNode, referenceNode) { - // You're not allowed to pass an element with no parent. - // I dunno how to make TS's typechecker see that. - // @ts-expect-error referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } @@ -305,11 +302,10 @@ function preLoadCss(cssUrl) { window.searchState.timeout = null; } }, - // @ts-expect-error isDisplayed: () => { const outputElement = window.searchState.outputElement(); - return outputElement && - outputElement.parentElement && + return !!outputElement && + !!outputElement.parentElement && outputElement.parentElement.id === ALTERNATIVE_DISPLAY_ID; }, // Sets the focus on the search bar at the top of the page @@ -325,8 +321,6 @@ function preLoadCss(cssUrl) { search = window.searchState.outputElement(); } switchDisplayedElement(search); - // @ts-expect-error - window.searchState.mouseMovedAfterSearch = false; document.title = window.searchState.title; }, removeQueryParameters: () => { @@ -503,34 +497,40 @@ function preLoadCss(cssUrl) { handleHashes(ev); } - // @ts-expect-error + /** + * @param {HTMLElement|null} elem + */ function openParentDetails(elem) { while (elem) { if (elem.tagName === "DETAILS") { + // @ts-expect-error elem.open = true; } - elem = elem.parentNode; + elem = elem.parentElement; } } - // @ts-expect-error + /** + * @param {string} id + */ function expandSection(id) { openParentDetails(document.getElementById(id)); } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleEscape(ev) { - // @ts-expect-error - searchState.clearInputTimeout(); - // @ts-expect-error - searchState.hideResults(); + window.searchState.clearInputTimeout(); + window.searchState.hideResults(); ev.preventDefault(); - // @ts-expect-error - searchState.defocus(); + window.searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips } - // @ts-expect-error + /** + * @param {KeyboardEvent} ev + */ function handleShortcut(ev) { // Don't interfere with browser shortcuts const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; @@ -538,8 +538,8 @@ function preLoadCss(cssUrl) { return; } - // @ts-expect-error - if (document.activeElement.tagName === "INPUT" && + if (document.activeElement && + document.activeElement.tagName === "INPUT" && // @ts-expect-error document.activeElement.type !== "checkbox" && // @ts-expect-error @@ -559,8 +559,7 @@ function preLoadCss(cssUrl) { case "S": case "/": ev.preventDefault(); - // @ts-expect-error - searchState.focus(); + window.searchState.focus(); break; case "+": @@ -586,7 +585,6 @@ function preLoadCss(cssUrl) { document.addEventListener("keydown", handleShortcut); function addSidebarItems() { - // @ts-expect-error if (!window.SIDEBAR_ITEMS) { return; } @@ -675,7 +673,6 @@ function preLoadCss(cssUrl) { } // - // @ts-expect-error window.register_implementors = imp => { const implementors = document.getElementById("implementors-list"); const synthetic_implementors = document.getElementById("synthetic-implementors-list"); @@ -767,9 +764,7 @@ function preLoadCss(cssUrl) { } } }; - // @ts-expect-error if (window.pending_implementors) { - // @ts-expect-error window.register_implementors(window.pending_implementors); } @@ -802,16 +797,14 @@ function preLoadCss(cssUrl) { * * - After processing all of the impls, it sorts the sidebar items by name. * - * @param {{[cratename: string]: Array>}} imp + * @param {rustdoc.TypeImpls} imp */ - // @ts-expect-error window.register_type_impls = imp => { // @ts-expect-error if (!imp || !imp[window.currentCrate]) { return; } - // @ts-expect-error - window.pending_type_impls = null; + window.pending_type_impls = undefined; const idMap = new Map(); let implementations = document.getElementById("implementations-list"); @@ -997,9 +990,7 @@ function preLoadCss(cssUrl) { list.replaceChildren(...newChildren); } }; - // @ts-expect-error if (window.pending_type_impls) { - // @ts-expect-error window.register_type_impls(window.pending_type_impls); } @@ -1695,8 +1686,7 @@ function preLoadCss(cssUrl) { addSidebarCrates(); onHashChange(null); window.addEventListener("hashchange", onHashChange); - // @ts-expect-error - searchState.setup(); + window.searchState.setup(); }()); // Hide, show, and resize the sidebar diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 1554c045a3271..4b43c00730d47 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -7,6 +7,8 @@ declare global { interface Window { /** Make the current theme easy to find */ currentTheme: HTMLLinkElement|null; + /** Generated in `render/context.rs` */ + SIDEBAR_ITEMS?: { [key: string]: string[] }; /** Used by the popover tooltip code. */ RUSTDOC_TOOLTIP_HOVER_MS: number; /** Used by the popover tooltip code. */ @@ -42,6 +44,17 @@ declare global { * Set up event listeners for a scraped source example. */ updateScrapedExample?: function(HTMLElement, HTMLElement), + /** + * register trait implementors, called by code generated in + * `write_shared.rs` + */ + register_implementors?: function(rustdoc.Implementors): void, + /** + * fallback in case `register_implementors` isn't defined yet. + */ + pending_implementors?: rustdoc.Implementors, + register_type_impls?: function(rustdoc.TypeImpls): void, + pending_type_impls?: rustdoc.TypeImpls, } interface HTMLElement { /** Used by the popover tooltip code. */ @@ -413,4 +426,16 @@ declare namespace rustdoc { }; type VlqData = VlqData[] | number; + + /** + * Maps from crate names to trait implementation data. + * Provied by generated `trait.impl` files. + */ + type Implementors = { + [key: string]: Array<[string, number, Array]> + } + + type TypeImpls = { + [cratename: string]: Array> + } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 9606ba76991a7..d65c13b2b6313 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -548,7 +548,18 @@ impl FromClean for GenericBound { } } Outlives(lifetime) => GenericBound::Outlives(convert_lifetime(lifetime)), - Use(args) => GenericBound::Use(args.into_iter().map(|arg| arg.to_string()).collect()), + Use(args) => GenericBound::Use( + args.iter() + .map(|arg| match arg { + clean::PreciseCapturingArg::Lifetime(lt) => { + PreciseCapturingArg::Lifetime(convert_lifetime(*lt)) + } + clean::PreciseCapturingArg::Param(param) => { + PreciseCapturingArg::Param(param.to_string()) + } + }) + .collect(), + ), } } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 7b6921afa0808..68e381fa3f171 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -143,7 +143,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { && self.cx.tcx.has_attr(def_id, sym::macro_export) && inserted.insert(def_id) { - let item = self.cx.tcx.hir().expect_item(local_def_id); + let item = self.cx.tcx.hir_expect_item(local_def_id); top_level_module .items .insert((local_def_id, Some(item.ident.name)), (item, None, None)); @@ -153,8 +153,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { self.cx.cache.hidden_cfg = self .cx .tcx - .hir() - .attrs(CRATE_HIR_ID) + .hir_attrs(CRATE_HIR_ID) .iter() .filter(|attr| attr.has_name(sym::doc)) .flat_map(|attr| attr.meta_item_list().into_iter().flatten()) @@ -245,7 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let document_hidden = self.cx.render_options.document_hidden; - let use_attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id)); + let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline) || (document_hidden && hir_attr_lists(use_attrs, sym::doc).has_word(sym::hidden)); @@ -449,7 +448,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue; } - let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); + let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id)); // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 8f6496e9626c8..8ec7cffe06620 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap = HashMap; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 40; +pub const FORMAT_VERSION: u32 = 41; /// The root of the emitted JSON blob. /// @@ -909,7 +909,7 @@ pub enum GenericBound { /// ``` Outlives(String), /// `use<'a, T>` precise-capturing bound syntax - Use(Vec), + Use(Vec), } /// A set of modifiers applied to a trait. @@ -927,6 +927,22 @@ pub enum TraitBoundModifier { MaybeConst, } +/// One precise capturing argument. See [the rust reference](https://doc.rust-lang.org/reference/types/impl-trait.html#precise-capturing). +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum PreciseCapturingArg { + /// A lifetime. + /// ```rust + /// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} + /// // ^^ + Lifetime(String), + /// A type or constant parameter. + /// ```rust + /// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} + /// // ^ ^ + Param(String), +} + /// Either a type or a constant, usually stored as the right-hand side of an equation in places like /// [`AssocItemConstraint`] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index dfc8f3bc7e0db..741d7e3fa16c1 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -386,7 +386,6 @@ impl Builder { // NOTE: this profile is effectively deprecated; do not add new components to it. let mut complete = default; complete.extend([ - Rls, RustAnalyzer, RustSrc, LlvmTools, @@ -475,7 +474,6 @@ impl Builder { // but might be marked as unavailable if they weren't built. PkgType::Clippy | PkgType::Miri - | PkgType::Rls | PkgType::RustAnalyzer | PkgType::Rustfmt | PkgType::LlvmTools diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 495cab582eb07..6ef8a0e83de3f 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -51,7 +51,6 @@ pkg_type! { Cargo = "cargo", HtmlDocs = "rust-docs", RustAnalysis = "rust-analysis", - Rls = "rls"; preview = true, RustAnalyzer = "rust-analyzer"; preview = true, Clippy = "clippy"; preview = true, Rustfmt = "rustfmt"; preview = true, @@ -77,7 +76,6 @@ impl PkgType { fn should_use_rust_version(&self) -> bool { match self { PkgType::Cargo => false, - PkgType::Rls => false, PkgType::RustAnalyzer => false, PkgType::Clippy => false, PkgType::Rustfmt => false, @@ -118,7 +116,6 @@ impl PkgType { HtmlDocs => HOSTS, JsonDocs => HOSTS, RustSrc => &["*"], - Rls => HOSTS, RustAnalyzer => HOSTS, Clippy => HOSTS, Miri => HOSTS, diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 2b59c218d57a1..f9a2f011a144f 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -465,7 +465,7 @@ impl Attributes { impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); if is_relevant_item(cx, item) { inline_always::check(cx, item.span, item.ident.name, attrs); } @@ -474,13 +474,13 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { if is_relevant_impl(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) { if is_relevant_trait(cx, item) { - inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id())); + inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id())); } } } diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index 085ed9222c91a..7c64bf46e7bd2 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -97,7 +97,7 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR } fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC)) } diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 66a3e5e3d3c7f..8d9222e4bf61e 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b) && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) - && cx.tcx.hir().attrs(impl_item_hir).is_empty() + && cx.tcx.hir_attrs(impl_item_hir).is_empty() { if adt_def.is_struct() { check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b)); diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index db3e6034c5baf..2ae35b4005579 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -384,7 +384,7 @@ fn check_unsafe_derive_deserialize<'tcx>( .tcx .inherent_impls(def.did()) .iter() - .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) + .map(|imp_did| cx.tcx.hir_expect_item(imp_did.expect_local())) .any(|imp| has_unsafe(cx, imp)) { span_lint_hir_and_then( diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs index e8638595c4b26..e75abf28bace8 100644 --- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs +++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs @@ -25,7 +25,7 @@ pub fn check( && cx .tcx .hir_parent_iter(owner_id.into()) - .any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id))) + .any(|(id, _node)| is_doc_hidden(cx.tcx.hir_attrs(id))) { return; } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 33ba401d60c21..9298f56b68bee 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -163,7 +163,6 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) { if cmt.place.projections.is_empty() { - let map = &self.cx.tcx.hir(); if is_argument(self.cx.tcx, cmt.hir_id) { // Skip closure arguments let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id); @@ -174,7 +173,7 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> { // skip if there is a `self` parameter binding to a type // that contains `Self` (i.e.: `self: Box`), see #4804 if let Some(trait_self_ty) = self.trait_self_ty { - if map.name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { + if self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) { return; } } diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 9bf3baba4b597..591912cc8d5e8 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -84,7 +84,7 @@ impl LateLintPass<'_> for ExhaustiveItems { _ => return, }; if cx.effective_visibilities.is_exported(item.owner_id.def_id) - && let attrs = cx.tcx.hir().attrs(item.hir_id()) + && let attrs = cx.tcx.hir_attrs(item.hir_id()) && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public()) { diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs index ff75fcf2b417c..5b42a40d850bb 100644 --- a/src/tools/clippy/clippy_lints/src/format_impl.rs +++ b/src/tools/clippy/clippy_lints/src/format_impl.rs @@ -209,9 +209,8 @@ impl FormatImplExpr<'_, '_> { // Handle dereference of &self -> self that is equivalent (i.e. via *self in fmt() impl) // Since the argument to fmt is itself a reference: &self let reference = peel_ref_operators(self.cx, arg); - let map = self.cx.tcx.hir(); // Is the reference self? - if path_to_local(reference).map(|x| map.name(x)) == Some(kw::SelfLower) { + if path_to_local(reference).map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) { let FormatTraitNames { name, .. } = self.format_trait_impl; span_lint( self.cx, diff --git a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs index 0bdb99d7b9a4d..8822b87f92f72 100644 --- a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs +++ b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs @@ -43,8 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes { let sm = cx.sess().source_map(); let mut span = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .filter(|i| i.is_doc_comment()) .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span())); diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index f1c9657f22404..c3e0d5e8b694d 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -21,7 +21,7 @@ use core::ops::ControlFlow; use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let hir::ItemKind::Fn { ref sig, @@ -51,7 +51,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind { let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); @@ -74,7 +74,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs index 5b58113169b1e..e1dd7872b9d48 100644 --- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs @@ -182,7 +182,7 @@ fn suggestion<'tcx>( } fn field_with_attrs_span(tcx: TyCtxt<'_>, field: &hir::ExprField<'_>) -> Span { - if let Some(attr) = tcx.hir().attrs(field.hir_id).first() { + if let Some(attr) = tcx.hir_attrs(field.hir_id).first() { field.span.with_lo(attr.span().lo()) } else { field.span diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs index 9b4a3b3f9c84c..6a436fb4a9d1e 100644 --- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs +++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs @@ -34,8 +34,7 @@ impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody { if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind && let Some(attr) = cx .tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .find(|a| a.has_name(sym::inline)) { diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index 20be22850b760..b712b351d063c 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -98,7 +98,7 @@ impl LateLintPass<'_> for MacroUseImports { if cx.sess().opts.edition >= Edition::Edition2018 && let hir::ItemKind::Use(path, _kind) = &item.kind && let hir_id = item.hir_id() - && let attrs = cx.tcx.hir().attrs(hir_id) + && let attrs = cx.tcx.hir_attrs(hir_id) && let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use)) && let Some(id) = path.res.iter().find_map(|res| match res { Res::Def(DefKind::Mod, id) => Some(id), diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 496e0660d4f9a..64b07a5536b4d 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -89,11 +89,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { match item.kind { ItemKind::Enum(def, _) if def.variants.len() > 1 => { let iter = def.variants.iter().filter_map(|v| { - (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))) + (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { "this seems like a manual implementation of the non-exhaustive pattern", |diag| { if let Some(non_exhaustive) = - attr::find_by_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive) + attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) { diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); } else { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index d697f427c7052..d29d1ea3e96d9 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -42,7 +42,7 @@ pub(super) fn check_match<'tcx>( cx, scrutinee, arms.iter() - .map(|arm| (cx.tcx.hir().attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), + .map(|arm| (cx.tcx.hir_attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)), e, false, ) diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index 41e4c75f843e5..250f17fa9025a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -75,7 +75,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id, } // the names technically don't have to match; this makes the lint more conservative - && cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id) + && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id) && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b) && pat_contains_local(lhs.pat, a_id) && pat_contains_local(rhs.pat, b_id) diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 1c64f78678aeb..7c190e123b72e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -41,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx .hir_parent_id_iter(id) - .any(|id| cx.tcx.hir().attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) + .any(|id| cx.tcx.hir_attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) } /// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 94d3657d9f123..7dde21d3edb13 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4731,7 +4731,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { } let name = impl_item.ident.name.as_str(); let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 47a9e17b3cfe1..3470c266c4917 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_crate(&mut self, cx: &LateContext<'tcx>) { - let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID); + let attrs = cx.tcx.hir_attrs(hir::CRATE_HIR_ID); self.check_missing_docs_attrs(cx, CRATE_DEF_ID, attrs, cx.tcx.def_span(CRATE_DEF_ID), "the", "crate"); } @@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); if !is_from_proc_macro(cx, it) { self.check_missing_docs_attrs(cx, it.owner_id.def_id, attrs, it.span, article, desc); } @@ -234,7 +234,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) { let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(trait_item.hir_id()); + let attrs = cx.tcx.hir_attrs(trait_item.hir_id()); if !is_from_proc_macro(cx, trait_item) { self.check_missing_docs_attrs(cx, trait_item.owner_id.def_id, attrs, trait_item.span, article, desc); } @@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id()); - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); if !is_from_proc_macro(cx, impl_item) { self.check_missing_docs_attrs(cx, impl_item.owner_id.def_id, attrs, impl_item.span, article, desc); } @@ -261,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { fn check_field_def(&mut self, cx: &LateContext<'tcx>, sf: &'tcx hir::FieldDef<'_>) { if !sf.is_positional() { - let attrs = cx.tcx.hir().attrs(sf.hir_id); + let attrs = cx.tcx.hir_attrs(sf.hir_id); if !is_from_proc_macro(cx, sf) { self.check_missing_docs_attrs(cx, sf.def_id, attrs, sf.span, "a", "struct field"); } @@ -270,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { } fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) { - let attrs = cx.tcx.hir().attrs(v.hir_id); + let attrs = cx.tcx.hir_attrs(v.hir_id); if !is_from_proc_macro(cx, v) { self.check_missing_docs_attrs(cx, v.def_id, attrs, v.span, "a", "variant"); } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 3cf1a80607e8b..2c578d816025f 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match it.kind { hir::ItemKind::Fn { .. } => { let desc = "a function"; - let attrs = cx.tcx.hir().attrs(it.hir_id()); + let attrs = cx.tcx.hir_attrs(it.hir_id()); check_missing_inline_attrs(cx, attrs, it.span, desc); }, hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => { @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { // an impl is not provided let desc = "a default trait method"; let item = cx.tcx.hir_trait_item(tit.id); - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); check_missing_inline_attrs(cx, attrs, item.span, desc); } }, @@ -168,7 +168,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { } } - let attrs = cx.tcx.hir().attrs(impl_item.hir_id()); + let attrs = cx.tcx.hir_attrs(impl_item.hir_id()); check_missing_inline_attrs(cx, attrs, impl_item.span, desc); } } diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index a7452c8a3c84e..be728e6c8b74b 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -334,7 +334,7 @@ impl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> { self.cx, MIXED_READ_WRITE_IN_EXPRESSION, expr.span, - format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)), + format!("unsequenced read of `{}`", self.cx.tcx.hir_name(self.var)), |diag| { diag.span_note( self.write_expr.span, diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs index 7eefb016aca98..c90019f6ee161 100644 --- a/src/tools/clippy/clippy_lints/src/needless_if.rs +++ b/src/tools/clippy/clippy_lints/src/needless_if.rs @@ -65,7 +65,7 @@ impl LateLintPass<'_> for NeedlessIf { stmt.span, "this `if` branch is empty", "you can remove it", - if cond.can_have_side_effects() || !cx.tcx.hir().attrs(stmt.hir_id).is_empty() { + if cond.can_have_side_effects() || !cx.tcx.hir_attrs(stmt.hir_id).is_empty() { // `{ foo }` or `{ foo } && bar` placed into a statement position would be // interpreted as a block statement, force it to be an expression if cond_snippet.starts_with('{') { diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 863a1f895c937..3efbed0c2365e 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -261,7 +261,7 @@ fn check<'tcx>( binding_id: HirId, ) -> Option<()> { let usage = first_usage(cx, binding_id, local_stmt.hir_id, block)?; - let binding_name = cx.tcx.hir().opt_name(binding_id)?; + let binding_name = cx.tcx.hir_opt_name(binding_id)?; let let_snippet = local_snippet_without_semicolon(cx, local)?; match usage.expr.kind { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index dc10de24bc8c7..576bb27b254c9 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // We don't check unsafe functions. return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index dc85176ebb9e9..7bee89086b80f 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { match kind { FnKind::ItemFn(.., header) => { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) { return; } diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs index 1baa3cb2f0fdc..fe8a02c64c660 100644 --- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -40,7 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind && !item.span.from_expansion() { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); let mut app = Applicability::MaybeIncorrect; let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app); for attr in attrs { diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index d4da12451f181..9b53608ae7f3c 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -351,7 +351,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, body_id) = &impl_item.kind { let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(item_def_id); + let item = cx.tcx.hir_expect_item(item_def_id); match &item.kind { ItemKind::Impl(Impl { diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs index c3c09946c27d1..378fed481f4fe 100644 --- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs +++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs @@ -181,7 +181,7 @@ fn in_impl<'tcx>( ) -> Option<(&'tcx rustc_hir::Ty<'tcx>, &'tcx rustc_hir::Ty<'tcx>)> { if let Some(block) = get_enclosing_block(cx, e.hir_id) && let Some(impl_def_id) = cx.tcx.impl_of_method(block.hir_id.owner.to_def_id()) - && let item = cx.tcx.hir().expect_item(impl_def_id.expect_local()) + && let item = cx.tcx.hir_expect_item(impl_def_id.expect_local()) && let ItemKind::Impl(item) = &item.kind && let Some(of_trait) = &item.of_trait && let Some(seg) = of_trait.path.segments.last() @@ -200,7 +200,7 @@ fn in_impl<'tcx>( fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool { if let ty::Adt(adt_def, _) = middle_ty.kind() && let Some(local_did) = adt_def.did().as_local() - && let item = cx.tcx.hir().expect_item(local_did) + && let item = cx.tcx.hir_expect_item(local_did) && let middle_ty_id = item.owner_id.to_def_id() && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind && let Res::Def(_, hir_ty_id) = path.res diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 49bc560834682..320c0286bb7be 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -280,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { if header.abi != ExternAbi::Rust { return; } - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); for a in attrs { if let Some(meta_items) = a.meta_item_list() { if a.has_name(sym::proc_macro_derive) diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs index db03657c9af43..fd21893232dbb 100644 --- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs +++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields { // Only pertains to fields that start with an underscore, and are public. if field.ident.as_str().starts_with('_') && is_visible(field) // We ignore fields that have `#[doc(hidden)]`. - && !is_doc_hidden(cx.tcx.hir().attrs(field.hir_id)) + && !is_doc_hidden(cx.tcx.hir_attrs(field.hir_id)) // We ignore fields that are `PhantomData`. && !is_path_lang_item(cx, field.ty, LangItem::PhantomData) { diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs index 6bd68dd4109d4..49b522994fbf7 100644 --- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs +++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs @@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { }, ), VecInitKind::WithExprCapacity(hir_id) => { - let e = cx.tcx.hir().expect_expr(hir_id); + let e = cx.tcx.hir_expect_expr(hir_id); span_lint_hir_and_then( cx, READ_ZERO_BYTE_VEC, diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index 5a25483c397c6..07ae92fa98439 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa // We only show this warning for public exported methods. && cx.effective_visibilities.is_exported(fn_def) // We don't want to emit this lint if the `#[must_use]` attribute is already there. - && !cx.tcx.hir().attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) + && !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) && cx.tcx.visibility(fn_def.to_def_id()).is_public() && let ret_ty = return_ty(cx, owner_id) && let self_arg = nth_arg(cx, owner_id, 0) diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 3ba6d6284592b..4cb73df8b488f 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -231,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && let Some(stmt) = block.stmts.iter().last() && let StmtKind::Let(local) = &stmt.kind && local.ty.is_none() - && cx.tcx.hir().attrs(local.hir_id).is_empty() + && cx.tcx.hir_attrs(local.hir_id).is_empty() && let Some(initexpr) = &local.init && let PatKind::Binding(_, local_id, _, _) = local.pat.kind && path_to_local_id(retexpr, local_id) @@ -401,7 +401,7 @@ fn check_final_expr<'tcx>( // This allows the addition of attributes, like `#[allow]` (See: clippy#9361) // `#[expect(clippy::needless_return)]` needs to be handled separately to // actually fulfill the expectation (clippy::#12998) - match cx.tcx.hir().attrs(expr.hir_id) { + match cx.tcx.hir_attrs(expr.hir_id) { [] => {}, [attr] => { if matches!(Level::from_attr(attr), Some(Level::Expect(_))) diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index fc02c3a51716e..8b2d597b9e323 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let item = cx.tcx.hir().expect_item(parent); + let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 746bf018bcc31..be533ca915ed4 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -429,8 +429,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span { span.to(cx .tcx - .hir() - .attrs(hir_id) + .hir_attrs(hir_id) .iter() .fold(span, |acc, attr| acc.to(attr.span()))) } diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index 2c6c75693166f..582aa6e6001e8 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { return; } let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; - let parent_item = cx.tcx.hir().expect_item(parent); + let parent_item = cx.tcx.hir_expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| { diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 6f6683eb97123..b466a8e127a94 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -318,7 +318,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> { { if call_to_unwrap == unwrappable.safe_to_unwrap { let is_entire_condition = unwrappable.is_entire_condition; - let unwrappable_variable_name = self.cx.tcx.hir().name(unwrappable.local_id); + let unwrappable_variable_name = self.cx.tcx.hir_name(unwrappable.local_id); let suggested_pattern = if call_to_unwrap { unwrappable.kind.success_variant_pattern() } else { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 9d8c161873c05..4309cd2c9abdf 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "author").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs index b108951978f30..9910be9bc2853 100644 --- a/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs +++ b/src/tools/clippy/clippy_lints/src/utils/dump_hir.rs @@ -59,6 +59,6 @@ impl<'tcx> LateLintPass<'tcx> for DumpHir { } fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { - let attrs = cx.tcx.hir().attrs(hir_id); + let attrs = cx.tcx.hir_attrs(hir_id); get_attr(cx.sess(), attrs, "dump").count() > 0 } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 89b4c48b8b116..16d51fa09025a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -247,7 +247,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<' /// This function extracts the version value of a `clippy::version` attribute if the given value has /// one pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option { - let attrs = cx.tcx.hir().attrs(item.hir_id()); + let attrs = cx.tcx.hir_attrs(item.hir_id()); attrs.iter().find_map(|attr| { if let hir::Attribute::Unparsed(attr_kind) = &attr // Identify attribute diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d89692468441c..80613a51c1400 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2036,15 +2036,14 @@ pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool { } pub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { - find_attr!(cx.tcx.hir().attrs(hir_id), AttributeKind::Repr(..)) + find_attr!(cx.tcx.hir_attrs(hir_id), AttributeKind::Repr(..)) } pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool { - let map = &tcx.hir(); let mut prev_enclosing_node = None; let mut enclosing_node = node; while Some(enclosing_node) != prev_enclosing_node { - if has_attr(map.attrs(enclosing_node), symbol) { + if has_attr(tcx.hir_attrs(enclosing_node), symbol) { return true; } prev_enclosing_node = Some(enclosing_node); @@ -2061,7 +2060,7 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) .any(|(id, _)| { has_attr( - tcx.hir().attrs(tcx.local_def_id_to_hir_id(id.def_id)), + tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)), sym::automatically_derived, ) }) @@ -2344,16 +2343,14 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_std) } pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { cx.tcx - .hir() - .attrs(hir::CRATE_HIR_ID) + .hir_attrs(hir::CRATE_HIR_ID) .iter() .any(|attr| attr.name_or_empty() == sym::no_core) } @@ -2643,8 +2640,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym // We could also check for the type name `test::TestDescAndFn` if let Res::Def(DefKind::Struct, _) = path.res { let has_test_marker = tcx - .hir() - .attrs(item.hir_id()) + .hir_attrs(item.hir_id()) .iter() .any(|a| a.has_name(sym::rustc_test_marker)); if has_test_marker { @@ -2688,7 +2684,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent /// use [`is_in_cfg_test`] pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir().attrs(id).iter().any(|attr| { + tcx.hir_attrs(id).iter().any(|attr| { if attr.has_name(sym::cfg) && let Some(items) = attr.meta_item_list() && let [item] = &*items @@ -2713,12 +2709,10 @@ pub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied. pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let hir = tcx.hir(); - tcx.has_attr(def_id, sym::cfg) || tcx .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) - .flat_map(|(parent_id, _)| hir.attrs(parent_id)) + .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs index 5bb2b12988a6c..0316de172de7f 100644 --- a/src/tools/clippy/clippy_utils/src/msrvs.rs +++ b/src/tools/clippy/clippy_utils/src/msrvs.rs @@ -108,7 +108,7 @@ impl Msrv { let start = cx.last_node_with_lint_attrs; if let Some(msrv_attr) = once(start) .chain(cx.tcx.hir_parent_id_iter(start)) - .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir().attrs(id))) + .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir_attrs(id))) { return Some(msrv_attr); } diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 24b4f0d9e6d81..9cc66593dcc3f 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -847,7 +847,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { let mut start_snip = snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability); // identifier referring to the variable currently triggered (i.e.: `fp`) - let ident_str = map.name(id).to_string(); + let ident_str = self.cx.tcx.hir_name(id).to_string(); // full identifier that includes projection (i.e.: `fp.field`) let ident_str_with_proj = snippet(self.cx, span, "..").to_string(); @@ -876,7 +876,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { // item is used in a call // i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)` ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) => { - let expr = self.cx.tcx.hir().expect_expr(cmt.hir_id); + let expr = self.cx.tcx.hir_expect_expr(cmt.hir_id); let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind(); if matches!(arg_ty_kind, ty::Ref(_, _, Mutability::Not)) { diff --git a/src/tools/rls/Cargo.toml b/src/tools/rls/Cargo.toml deleted file mode 100644 index b7aa659c25a94..0000000000000 --- a/src/tools/rls/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "rls" -version = "2.0.0" -edition = "2021" -license = "Apache-2.0/MIT" - -[dependencies] -serde_json = "1.0.83" diff --git a/src/tools/rls/README.md b/src/tools/rls/README.md deleted file mode 100644 index 43c331c413f5c..0000000000000 --- a/src/tools/rls/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# RLS Stub - -RLS has been replaced with [rust-analyzer](https://rust-analyzer.github.io/). - -This directory contains a stub which replaces RLS with a simple LSP server -which only displays an alert to the user that RLS is no longer available. diff --git a/src/tools/rls/src/main.rs b/src/tools/rls/src/main.rs deleted file mode 100644 index 3a95b47cd4dc4..0000000000000 --- a/src/tools/rls/src/main.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! RLS stub. -//! -//! This is a small stub that replaces RLS to alert the user that RLS is no -//! longer available. - -use std::error::Error; -use std::io::{BufRead, Write}; - -use serde_json::Value; - -const ALERT_MSG: &str = "\ -RLS is no longer available as of Rust 1.65. -Consider migrating to rust-analyzer instead. -See https://rust-analyzer.github.io/ for installation instructions. -"; - -fn main() { - if let Err(e) = run() { - eprintln!("error: {e}"); - std::process::exit(1); - } -} - -struct Message { - method: Option, -} - -fn run() -> Result<(), Box> { - let mut stdin = std::io::stdin().lock(); - let mut stdout = std::io::stdout().lock(); - - let init = read_message(&mut stdin)?; - if init.method.as_deref() != Some("initialize") { - return Err(format!("expected initialize, got {:?}", init.method).into()); - } - // No response, the LSP specification says that `showMessageRequest` may - // be posted before during this phase. - - // message_type 1 is "Error" - let alert = serde_json::json!({ - "jsonrpc": "2.0", - "id": 1, - "method": "window/showMessageRequest", - "params": { - "message_type": "1", - "message": ALERT_MSG - } - }); - write_message_raw(&mut stdout, serde_json::to_string(&alert).unwrap())?; - - loop { - let message = read_message(&mut stdin)?; - if message.method.as_deref() == Some("shutdown") { - std::process::exit(0); - } - } -} - -fn read_message_raw(reader: &mut R) -> Result> { - let mut content_length: usize = 0; - - // Read headers. - loop { - let mut line = String::new(); - reader.read_line(&mut line)?; - if line.is_empty() { - return Err("remote disconnected".into()); - } - if line == "\r\n" { - break; - } - if line.to_lowercase().starts_with("content-length:") { - let value = &line[15..].trim(); - content_length = usize::from_str_radix(value, 10)?; - } - } - if content_length == 0 { - return Err("no content-length".into()); - } - - let mut buffer = vec![0; content_length]; - reader.read_exact(&mut buffer)?; - let content = String::from_utf8(buffer)?; - - Ok(content) -} - -fn read_message(reader: &mut R) -> Result> { - let m = read_message_raw(reader)?; - match serde_json::from_str::(&m) { - Ok(message) => Ok(Message { - method: message.get("method").and_then(|value| value.as_str().map(String::from)), - }), - Err(e) => Err(format!("failed to parse message {m}\n{e}").into()), - } -} - -fn write_message_raw(mut writer: W, output: String) -> Result<(), Box> { - write!(writer, "Content-Length: {}\r\n\r\n{}", output.len(), output)?; - writer.flush()?; - Ok(()) -} diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs index edf7658d25fdc..08ee5c16c122f 100644 --- a/src/tools/tidy/src/walk.rs +++ b/src/tools/tidy/src/walk.rs @@ -32,8 +32,6 @@ pub fn filter_dirs(path: &Path) -> bool { "src/doc/rustc-dev-guide", "src/doc/reference", "src/gcc", - // Filter RLS output directories - "target/rls", "src/bootstrap/target", "vendor", ]; diff --git a/tests/debuginfo/pretty-huge-vec.rs b/tests/debuginfo/pretty-huge-vec.rs index 093fbc5b12d2e..6938158e365e5 100644 --- a/tests/debuginfo/pretty-huge-vec.rs +++ b/tests/debuginfo/pretty-huge-vec.rs @@ -1,5 +1,6 @@ //@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) +//@ ignore-aix: FIXME(#137965) //@ compile-flags:-g // === GDB TESTS =================================================================================== diff --git a/tests/pretty/hir-pretty-attr.pp b/tests/pretty/hir-pretty-attr.pp index 586810b004662..d8cc8c424ca5f 100644 --- a/tests/pretty/hir-pretty-attr.pp +++ b/tests/pretty/hir-pretty-attr.pp @@ -6,6 +6,6 @@ //@ pretty-mode:hir //@ pp-exact:hir-pretty-attr.pp -#[attr="Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])")] +#[attr = Repr([ReprC, ReprPacked(Align(4 bytes)), ReprTransparent])] struct Example { } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index e5ae943538842..35f716c24c71a 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -60,7 +60,8 @@ fn main() { } fn find_lld_version_in_logs(stderr: String) -> bool { - let lld_version_re = - Regex::new(r"^warning: linker std(out|err): LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + // Strip the `-Wlinker-messages` wrappers prefixing the linker output. + let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, ""); + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs index 82437f5ef03bb..f2bed77902b03 100644 --- a/tests/rustdoc-json/enums/discriminant/struct.rs +++ b/tests/rustdoc-json/enums/discriminant/struct.rs @@ -1,5 +1,5 @@ #[repr(i32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(SignedInt(I32))])\")]\n"]' +//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]' pub enum Foo { //@ is "$.index[*][?(@.name=='Struct')].inner.variant.discriminant" null //@ count "$.index[*][?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0 diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs index 25bba07e8f796..201c1cdc88e7e 100644 --- a/tests/rustdoc-json/enums/discriminant/tuple.rs +++ b/tests/rustdoc-json/enums/discriminant/tuple.rs @@ -1,5 +1,5 @@ #[repr(u32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(UnsignedInt(U32))])\")]\n"]' +//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]' pub enum Foo { //@ is "$.index[*][?(@.name=='Tuple')].inner.variant.discriminant" null //@ count "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0 diff --git a/tests/rustdoc-json/impl-trait-precise-capturing.rs b/tests/rustdoc-json/impl-trait-precise-capturing.rs index 52252560e6fda..06be95099b4d5 100644 --- a/tests/rustdoc-json/impl-trait-precise-capturing.rs +++ b/tests/rustdoc-json/impl-trait-precise-capturing.rs @@ -1,4 +1,4 @@ -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0]" \"\'a\" -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1]" \"T\" -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2]" \"N\" +//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0].lifetime" \"\'a\" +//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1].param" \"T\" +//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2].param" \"N\" pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} diff --git a/tests/ui/associated-type-bounds/hrtb.rs b/tests/ui/associated-type-bounds/hrtb.rs index 1bf574f2e6518..8ff7faec3a0f0 100644 --- a/tests/ui/associated-type-bounds/hrtb.rs +++ b/tests/ui/associated-type-bounds/hrtb.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) trait A<'a> {} trait B<'b> {} diff --git a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs index ed1c1fa6f039a..1c09ff3d3fb86 100644 --- a/tests/ui/associated-type-bounds/supertrait-defines-ty.rs +++ b/tests/ui/associated-type-bounds/supertrait-defines-ty.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) // Make sure that we don't look into associated type bounds when looking for // supertraits that define an associated type. Fixes #76593. diff --git a/tests/ui/consts/large_const_alloc.rs b/tests/ui/consts/large_const_alloc.rs index 14edc1bb69610..3573a018630f6 100644 --- a/tests/ui/consts/large_const_alloc.rs +++ b/tests/ui/consts/large_const_alloc.rs @@ -2,6 +2,9 @@ // on 32bit and 16bit platforms it is plausible that the maximum allocation size will succeed // FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger //@ ignore-aarch64-unknown-linux-gnu +// AIX will allow the allocation to go through, and get SIGKILL when zero initializing +// the overcommitted page. +//@ ignore-aix const FOO: () = { // 128 TiB, unlikely anyone has that much RAM diff --git a/tests/ui/consts/large_const_alloc.stderr b/tests/ui/consts/large_const_alloc.stderr index fa7d5977a9567..f3f3de7af63ac 100644 --- a/tests/ui/consts/large_const_alloc.stderr +++ b/tests/ui/consts/large_const_alloc.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/large_const_alloc.rs:8:13 + --> $DIR/large_const_alloc.rs:11:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler error[E0080]: could not evaluate static initializer - --> $DIR/large_const_alloc.rs:13:13 + --> $DIR/large_const_alloc.rs:16:13 | LL | let x = [0_u8; (1 << 47) - 1]; | ^^^^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs index 53618e2e86acd..75765596fa172 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.rs @@ -5,6 +5,9 @@ //@ only-64bit // FIXME (#135952) In some cases on AArch64 Linux the diagnostic does not trigger //@ ignore-aarch64-unknown-linux-gnu +// AIX will allow the allocation to go through, and get SIGKILL when zero initializing +// the overcommitted page. +//@ ignore-aix pub struct Data([u8; (1 << 47) - 1]); const _: &'static Data = &Data([0; (1 << 47) - 1]); diff --git a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr index aac805dbd8c79..02180c1e4c683 100644 --- a/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr +++ b/tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/promoted_running_out_of_memory_issue-130687.rs:10:32 + --> $DIR/promoted_running_out_of_memory_issue-130687.rs:13:32 | LL | const _: &'static Data = &Data([0; (1 << 47) - 1]); | ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler diff --git a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr index bc8edd847cc0f..30e36acb871a4 100644 --- a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr +++ b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr @@ -5,6 +5,7 @@ LL | #![allow(unqualified_local_imports)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `unqualified_local_imports` lint is unstable + = note: see issue #138299 for more information = help: add `#![feature(unqualified_local_imports)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: `#[warn(unknown_lints)]` on by default diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr index 192b5eebdaac8..4f1d339bc999d 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr @@ -1,8 +1,8 @@ -error[E0275]: overflow evaluating the requirement `Loop == _` +error[E0271]: type mismatch resolving `Loop normalizes-to _` --> $DIR/inherent-impls-overflow.rs:10:6 | LL | impl Loop {} - | ^^^^ + | ^^^^ types differ error: type parameter `T` is only used recursively --> $DIR/inherent-impls-overflow.rs:14:24 @@ -36,4 +36,5 @@ LL | impl Poly0<()> {} error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0275`. +Some errors have detailed explanations: E0271, E0275. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs index 1397695a3fe41..0d5ec7d153073 100644 --- a/tests/ui/lazy-type-alias/inherent-impls-overflow.rs +++ b/tests/ui/lazy-type-alias/inherent-impls-overflow.rs @@ -9,7 +9,7 @@ type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop` impl Loop {} //[current]~^ ERROR overflow normalizing the type alias `Loop` -//[next]~^^ ERROR overflow evaluating the requirement `Loop == _` +//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _` type Poly0 = Poly1<(T,)>; //[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>` diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs index 3238f02836283..28fd66cd1694a 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs @@ -6,9 +6,11 @@ trait Overflow { type Assoc; } -impl Overflow for T { - type Assoc = ::Assoc; - //~^ ERROR: overflow +impl Overflow for T +where + (T,): Overflow +{ + type Assoc = <(T,) as Overflow>::Assoc; } diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index 294fa0d7613c5..34a45e9363069 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -1,19 +1,15 @@ -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18 - | -LL | type Assoc = ::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^ - error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1 + --> $DIR/trait_ref_is_knowable-norm-overflow.rs:20:1 | LL | impl Trait for T {} | ------------------------- first implementation here LL | struct LocalTy; LL | impl Trait for ::Assoc {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + | + = note: overflow evaluating the requirement `_ == ::Assoc` + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0275. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs b/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs new file mode 100644 index 0000000000000..ec478aa02b770 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/cyclic-normalization-to-error-nalgebra.rs @@ -0,0 +1,21 @@ +// Regression test for trait-system-refactor-initiative#114. +// +// We previously treated the cycle when trying to use the +// `>::Output: DimMin` where-bound when +// normalizing `>::Output` as ambiguous, causing +// this to error. + +//@ check-pass +//@ compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver + +pub trait DimMin { + type Output; +} +pub fn repro, C>() +where + >::Output: DimMin>::Output>, +{ +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs new file mode 100644 index 0000000000000..46dd6adf66225 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.rs @@ -0,0 +1,21 @@ +// If we treat known inductive cycles as errors, this test compiles +// as normalizing `Overflow::Assoc` fails. +// +// As coherence already uses the new solver on stable, this change +// would require an FCP. + +trait Trait { + type Assoc; +} + +struct Overflow; +impl Trait for Overflow { + type Assoc = ::Assoc; +} + +trait Overlap {} +impl Overlap, U> for T {} +impl Overlap for Overflow {} +//~^ ERROR conflicting implementations of trait `Overlap<::Assoc, _>` for type `Overflow` + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr new file mode 100644 index 0000000000000..6605a28d54771 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/unproductive-in-coherence.stderr @@ -0,0 +1,11 @@ +error[E0119]: conflicting implementations of trait `Overlap<::Assoc, _>` for type `Overflow` + --> $DIR/unproductive-in-coherence.rs:18:1 + | +LL | impl Overlap, U> for T {} + | ----------------------------------------------------- first implementation here +LL | impl Overlap for Overflow {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Overflow` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs index 0f01a453b332e..94a9484ecdcf1 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.rs @@ -13,12 +13,7 @@ fn needs_bar() {} fn test::Assoc2> + Foo2::Assoc1>>() { needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1 == _` - //~| ERROR overflow evaluating the requirement `::Assoc1: Sized` - //~| ERROR overflow evaluating the requirement `::Assoc1: Bar` + //~^ ERROR the trait bound `::Assoc1: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr index 2b0e57966fe7b..6f5111a6193ca 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization-2.stderr @@ -1,59 +1,19 @@ -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` +error[E0277]: the trait bound `::Assoc1: Bar` is not satisfied --> $DIR/recursive-self-normalization-2.rs:15:17 | LL | needs_bar::(); - | ^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc1: Bar` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ + | ^^^^^^^^^ the trait `Bar` is not implemented for `::Assoc1` | note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization-2.rs:12:17 | LL | fn needs_bar() {} | ^^^ required by this bound in `needs_bar` - -error[E0275]: overflow evaluating the requirement `::Assoc1: Sized` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ - | -note: required by an implicit `Sized` bound in `needs_bar` - --> $DIR/recursive-self-normalization-2.rs:12:14 - | -LL | fn needs_bar() {} - | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn needs_bar() {} - | ++++++++ - -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0275]: overflow evaluating the requirement `::Assoc1 == _` - --> $DIR/recursive-self-normalization-2.rs:15:17 - | -LL | needs_bar::(); - | ^^^^^^^^^ +help: consider further restricting the associated type | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | fn test::Assoc2> + Foo2::Assoc1>>() where ::Assoc1: Bar { + | ++++++++++++++++++++++++++++++ -error: aborting due to 6 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs index f435b48737e23..f441ac499f99c 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.rs @@ -9,12 +9,7 @@ fn needs_bar() {} fn test::Assoc>>() { needs_bar::(); - //~^ ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc == _` - //~| ERROR overflow evaluating the requirement `::Assoc: Sized` - //~| ERROR overflow evaluating the requirement `::Assoc: Bar` + //~^ ERROR the trait bound `::Assoc: Bar` is not satisfied } fn main() {} diff --git a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr index af8504dcaeeea..c551823468741 100644 --- a/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr +++ b/tests/ui/traits/next-solver/overflow/recursive-self-normalization.stderr @@ -1,59 +1,19 @@ -error[E0275]: overflow evaluating the requirement `::Assoc == _` +error[E0277]: the trait bound `::Assoc: Bar` is not satisfied --> $DIR/recursive-self-normalization.rs:11:17 | LL | needs_bar::(); - | ^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc: Bar` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ + | ^^^^^^^^ the trait `Bar` is not implemented for `::Assoc` | note: required by a bound in `needs_bar` --> $DIR/recursive-self-normalization.rs:8:17 | LL | fn needs_bar() {} | ^^^ required by this bound in `needs_bar` - -error[E0275]: overflow evaluating the requirement `::Assoc: Sized` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ - | -note: required by an implicit `Sized` bound in `needs_bar` - --> $DIR/recursive-self-normalization.rs:8:14 - | -LL | fn needs_bar() {} - | ^ required by the implicit `Sized` requirement on this type parameter in `needs_bar` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn needs_bar() {} - | ++++++++ - -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:5 - | -LL | needs_bar::(); - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0275]: overflow evaluating the requirement `::Assoc == _` - --> $DIR/recursive-self-normalization.rs:11:17 - | -LL | needs_bar::(); - | ^^^^^^^^ +help: consider further restricting the associated type | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | fn test::Assoc>>() where ::Assoc: Bar { + | ++++++++++++++++++++++++++++ -error: aborting due to 6 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs index 24a32d8a9acf9..dda362a595e24 100644 --- a/tests/ui/unpretty/deprecated-attr.rs +++ b/tests/ui/unpretty/deprecated-attr.rs @@ -1,8 +1,6 @@ //@ compile-flags: -Zunpretty=hir //@ check-pass -// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is -// slightly broken. #[deprecated] pub struct PlainDeprecated; diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index 675351351a0c6..42de7b4533e51 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -5,24 +5,21 @@ extern crate std; //@ compile-flags: -Zunpretty=hir //@ check-pass -// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is -// slightly broken. -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -suggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}] struct PlainDeprecated; -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: +"here's why this is deprecated"}}] struct DirectNote; -#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: Unspecified, note: +"here's why this is deprecated"}}] struct ExplicitNote; -#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), +note: "here's why this is deprecated"}}] struct SinceAndNote; -#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note: -here's why this is deprecatedsuggestion: }span: }")] +#[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), +note: "here's why this is deprecated"}}] struct FlippedOrder;