From b65fab62999e96acd3683826ffd4140091f185f2 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 14 Aug 2025 00:28:44 -0700 Subject: Move `IntoDiagArg` earlier in the dependency chains `rustc_errors` depends on numerous crates, solely to implement its `IntoDiagArg` trait on types from those crates. Many crates depend on `rustc_errors`, and it's on the critical path. We can't swap things around to make all of those crates depend on `rustc_errors` instead, because `rustc_errors` would end up in dependency cycles. Instead, move `IntoDiagArg` into `rustc_error_messages`, which has far fewer dependencies, and then have most of these crates depend on `rustc_error_messages`. This allows `rustc_errors` to drop dependencies on several crates, including the large `rustc_target`. (This doesn't fully reduce dependency chains yet, as `rustc_errors` still depends on `rustc_hir` which depends on `rustc_target`. That will get fixed in a subsequent commit.) --- compiler/rustc_errors/src/codes.rs | 2 + compiler/rustc_errors/src/diagnostic.rs | 52 +--- compiler/rustc_errors/src/diagnostic_impls.rs | 326 +------------------------- compiler/rustc_errors/src/lib.rs | 18 +- 4 files changed, 19 insertions(+), 379 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs index 947cf27ca79..787a8af99b1 100644 --- a/compiler/rustc_errors/src/codes.rs +++ b/compiler/rustc_errors/src/codes.rs @@ -20,6 +20,8 @@ impl fmt::Display for ErrCode { } } +rustc_error_messages::into_diag_arg_using_display!(ErrCode); + macro_rules! define_error_code_constants_and_diagnostics_table { ($($name:ident: $num:literal,)*) => ( $( diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index e579370ce4e..183dceddd2c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use std::thread::panicking; use rustc_data_structures::fx::FxIndexMap; -use rustc_error_messages::{FluentValue, fluent_value_from_str_list_sep_by_and}; +use rustc_error_messages::{DiagArgName, DiagArgValue, IntoDiagArg}; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; use rustc_span::source_map::Spanned; @@ -22,26 +22,6 @@ use crate::{ Suggestions, }; -/// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of -/// `DiagArg` are converted to `FluentArgs` (consuming the collection) at the start of diagnostic -/// emission. -pub type DiagArg<'iter> = (&'iter DiagArgName, &'iter DiagArgValue); - -/// Name of a diagnostic argument. -pub type DiagArgName = Cow<'static, str>; - -/// Simplified version of `FluentValue` that can implement `Encodable` and `Decodable`. Converted -/// to a `FluentValue` by the emitter to be used in diagnostic translation. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] -pub enum DiagArgValue { - Str(Cow<'static, str>), - // This gets converted to a `FluentNumber`, which is an `f64`. An `i32` - // safely fits in an `f64`. Any integers bigger than that will be converted - // to strings in `into_diag_arg` and stored using the `Str` variant. - Number(i32), - StrListSepByAnd(Vec>), -} - pub type DiagArgMap = FxIndexMap; /// Trait for types that `Diag::emit` can return as a "guarantee" (or "proof") @@ -143,36 +123,6 @@ where } } -/// Converts a value of a type into a `DiagArg` (typically a field of an `Diag` struct). -/// Implemented as a custom trait rather than `From` so that it is implemented on the type being -/// converted rather than on `DiagArgValue`, which enables types from other `rustc_*` crates to -/// implement this. -pub trait IntoDiagArg { - /// Convert `Self` into a `DiagArgValue` suitable for rendering in a diagnostic. - /// - /// It takes a `path` where "long values" could be written to, if the `DiagArgValue` is too big - /// for displaying on the terminal. This path comes from the `Diag` itself. When rendering - /// values that come from `TyCtxt`, like `Ty<'_>`, they can use `TyCtxt::short_string`. If a - /// value has no shortening logic that could be used, the argument can be safely ignored. - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue; -} - -impl IntoDiagArg for DiagArgValue { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - self - } -} - -impl From for FluentValue<'static> { - fn from(val: DiagArgValue) -> Self { - match val { - DiagArgValue::Str(s) => From::from(s), - DiagArgValue::Number(n) => From::from(n), - DiagArgValue::StrListSepByAnd(l) => fluent_value_from_str_list_sep_by_and(l), - } - } -} - /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic]. #[rustc_diagnostic_item = "Subdiagnostic"] diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 698b6b8d504..435d16a8380 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -1,340 +1,22 @@ -use std::backtrace::Backtrace; use std::borrow::Cow; -use std::fmt; -use std::num::ParseIntError; -use std::path::{Path, PathBuf}; -use std::process::ExitStatus; use rustc_abi::TargetDataLayoutErrors; -use rustc_ast::util::parser::ExprPrecedence; -use rustc_ast_pretty::pprust; -use rustc_hir::RustcVersion; -use rustc_hir::attrs::{MirDialect, MirPhase}; +use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::Subdiagnostic; -use rustc_span::edition::Edition; -use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol}; -use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTuple}; -use rustc_type_ir::{ClosureKind, FloatTy}; -use {rustc_ast as ast, rustc_hir as hir}; +use rustc_span::{Span, Symbol}; use crate::diagnostic::DiagLocation; use crate::{ - Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level, - Subdiagnostic, fluent_generated as fluent, + Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, + fluent_generated as fluent, }; -pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display); - -impl IntoDiagArg for DiagArgFromDisplay<'_> { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.0.to_string().into_diag_arg(path) - } -} - -impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> { - fn from(t: &'a dyn fmt::Display) -> Self { - DiagArgFromDisplay(t) - } -} - -impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> { - fn from(t: &'a T) -> Self { - DiagArgFromDisplay(t) - } -} - -impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.clone().into_diag_arg(path) - } -} - -#[macro_export] -macro_rules! into_diag_arg_using_display { - ($( $ty:ty ),+ $(,)?) => { - $( - impl IntoDiagArg for $ty { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(path) - } - } - )+ - } -} - -macro_rules! into_diag_arg_for_number { - ($( $ty:ty ),+ $(,)?) => { - $( - impl IntoDiagArg for $ty { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - // Convert to a string if it won't fit into `Number`. - #[allow(irrefutable_let_patterns)] - if let Ok(n) = TryInto::::try_into(self) { - DiagArgValue::Number(n) - } else { - self.to_string().into_diag_arg(path) - } - } - } - )+ - } -} - -into_diag_arg_using_display!( - ast::ParamKindOrd, - std::io::Error, - Box, - std::num::NonZero, - hir::Target, - Edition, - Ident, - MacroRulesNormalizedIdent, - ParseIntError, - StackProtector, - &TargetTuple, - SplitDebuginfo, - ExitStatus, - ErrCode, - rustc_abi::ExternAbi, -); - -impl IntoDiagArg for RustcVersion { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.to_string())) - } -} - -impl IntoDiagArg for rustc_type_ir::TraitRef { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(path) - } -} - -impl IntoDiagArg for rustc_type_ir::ExistentialTraitRef { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(path) - } -} - -impl IntoDiagArg for rustc_type_ir::UnevaluatedConst { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - format!("{self:?}").into_diag_arg(path) - } -} - -impl IntoDiagArg for rustc_type_ir::FnSig { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - format!("{self:?}").into_diag_arg(path) - } -} - -impl IntoDiagArg for rustc_type_ir::Binder -where - T: IntoDiagArg, -{ - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.skip_binder().into_diag_arg(path) - } -} - -into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); - -impl IntoDiagArg for bool { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - if self { - DiagArgValue::Str(Cow::Borrowed("true")) - } else { - DiagArgValue::Str(Cow::Borrowed("false")) - } - } -} - -impl IntoDiagArg for char { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(format!("{self:?}"))) - } -} - -impl IntoDiagArg for Vec { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::StrListSepByAnd( - self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(), - ) - } -} - -impl IntoDiagArg for Symbol { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_ident_string().into_diag_arg(path) - } -} - -impl<'a> IntoDiagArg for &'a str { - fn into_diag_arg(self, path: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(path) - } -} - -impl IntoDiagArg for String { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self)) - } -} - -impl<'a> IntoDiagArg for Cow<'a, str> { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.into_owned())) - } -} - -impl<'a> IntoDiagArg for &'a Path { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.display().to_string())) - } -} - -impl IntoDiagArg for PathBuf { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.display().to_string())) - } -} - -impl IntoDiagArg for PanicStrategy { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.desc().to_string())) - } -} - -impl IntoDiagArg for hir::ConstContext { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Borrowed(match self { - hir::ConstContext::ConstFn => "const_fn", - hir::ConstContext::Static(_) => "static", - hir::ConstContext::Const { .. } => "const", - })) - } -} - -impl IntoDiagArg for ast::Expr { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(pprust::expr_to_string(&self))) - } -} - -impl IntoDiagArg for ast::Path { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(pprust::path_to_string(&self))) - } -} - -impl IntoDiagArg for ast::token::Token { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(pprust::token_to_string(&self)) - } -} - -impl IntoDiagArg for ast::token::TokenKind { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(pprust::token_kind_to_string(&self)) - } -} - -impl IntoDiagArg for FloatTy { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Borrowed(self.name_str())) - } -} - -impl IntoDiagArg for std::ffi::CString { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) - } -} - -impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned())) - } -} - -impl IntoDiagArg for ast::Visibility { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - let s = pprust::vis_to_string(&self); - let s = s.trim_end().to_string(); - DiagArgValue::Str(Cow::Owned(s)) - } -} - -impl IntoDiagArg for rustc_lint_defs::Level { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Borrowed(self.to_cmd_flag())) - } -} - -impl IntoDiagArg for hir::def::Res { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Borrowed(self.descr())) - } -} - impl IntoDiagArg for DiagLocation { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::from(self.to_string())) } } -impl IntoDiagArg for Backtrace { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::from(self.to_string())) - } -} - -impl IntoDiagArg for Level { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::from(self.to_string())) - } -} - -impl IntoDiagArg for ClosureKind { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(self.as_str().into()) - } -} - -impl IntoDiagArg for hir::def::Namespace { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Str(Cow::Borrowed(self.descr())) - } -} - -impl IntoDiagArg for ExprPrecedence { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - DiagArgValue::Number(self as i32) - } -} - -impl IntoDiagArg for MirDialect { - fn into_diag_arg(self, _path: &mut Option) -> DiagArgValue { - let arg = match self { - MirDialect::Analysis => "analysis", - MirDialect::Built => "built", - MirDialect::Runtime => "runtime", - }; - DiagArgValue::Str(Cow::Borrowed(arg)) - } -} - -impl IntoDiagArg for MirPhase { - fn into_diag_arg(self, _path: &mut Option) -> DiagArgValue { - let arg = match self { - MirPhase::Initial => "initial", - MirPhase::PostCleanup => "post-cleanup", - MirPhase::Optimized => "optimized", - }; - DiagArgValue::Str(Cow::Borrowed(arg)) - } -} - #[derive(Clone)] pub struct DiagSymbolList(Vec); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 2534cddf105..0a2bfee8b29 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -41,12 +41,11 @@ use std::{fmt, panic}; use Level::*; pub use codes::*; pub use diagnostic::{ - BugAbort, Diag, DiagArg, DiagArgMap, DiagArgName, DiagArgValue, DiagInner, DiagStyledString, - Diagnostic, EmissionGuarantee, FatalAbort, IntoDiagArg, LintDiagnostic, StringPart, Subdiag, - Subdiagnostic, + BugAbort, Diag, DiagArgMap, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee, + FatalAbort, LintDiagnostic, StringPart, Subdiag, Subdiagnostic, }; pub use diagnostic_impls::{ - DiagArgFromDisplay, DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter, + DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter, IndicateAnonymousLifetime, SingleLabelManySpans, }; pub use emitter::ColorConfig; @@ -56,8 +55,9 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{DynSend, Lock}; pub use rustc_error_messages::{ - DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, - SubdiagMessage, fallback_fluent_bundle, fluent_bundle, + DiagArg, DiagArgFromDisplay, DiagArgName, DiagArgValue, DiagMessage, FluentBundle, IntoDiagArg, + LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, + fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display, }; use rustc_hashes::Hash128; use rustc_hir::HirId; @@ -1999,6 +1999,12 @@ impl Level { } } +impl IntoDiagArg for Level { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + DiagArgValue::Str(Cow::from(self.to_string())) + } +} + // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite. pub fn elided_lifetime_in_path_suggestion( source_map: &SourceMap, -- cgit 1.4.1-3-g733a5 From f3c8b7ad40c405989be968dc170e487d360fd6da Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 14 Aug 2025 01:33:59 -0700 Subject: Split `rustc_hir_id` out of `rustc_hir` Some crates depend on `rustc_hir` but only want `HirId` and similar id types. `rustc_hir` is a heavy dependency, since it pulls in `rustc_target`. Split these types out into their own crate `rustc_hir_id`. This allows `rustc_errors` to drop its direct dependency on `rustc_hir`. (`rustc_errors` still depends on `rustc_hir` indirectly through `rustc_lint_defs`; a subsequent commit will fix that.) --- Cargo.lock | 15 ++- compiler/rustc_errors/Cargo.toml | 2 +- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_hir/Cargo.toml | 1 + compiler/rustc_hir/src/hir_id.rs | 173 ------------------------- compiler/rustc_hir/src/lib.rs | 6 +- compiler/rustc_hir/src/stable_hash_impls.rs | 21 +-- compiler/rustc_hir_id/Cargo.toml | 13 ++ compiler/rustc_hir_id/src/lib.rs | 194 ++++++++++++++++++++++++++++ compiler/rustc_lint_defs/Cargo.toml | 1 + compiler/rustc_lint_defs/src/lib.rs | 6 +- 11 files changed, 230 insertions(+), 204 deletions(-) delete mode 100644 compiler/rustc_hir/src/hir_id.rs create mode 100644 compiler/rustc_hir_id/Cargo.toml create mode 100644 compiler/rustc_hir_id/src/lib.rs (limited to 'compiler/rustc_errors/src') diff --git a/Cargo.lock b/Cargo.lock index 4a72b78f774..a0d1b250abc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3803,7 +3803,7 @@ dependencies = [ "rustc_error_messages", "rustc_fluent_macro", "rustc_hashes", - "rustc_hir", + "rustc_hir_id", "rustc_index", "rustc_lexer", "rustc_lint_defs", @@ -3899,6 +3899,7 @@ dependencies = [ "rustc_data_structures", "rustc_error_messages", "rustc_hashes", + "rustc_hir_id", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3936,6 +3937,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "rustc_hir_id" +version = "0.0.0" +dependencies = [ + "rustc_data_structures", + "rustc_index", + "rustc_macros", + "rustc_serialize", + "rustc_span", +] + [[package]] name = "rustc_hir_pretty" version = "0.0.0" @@ -4128,6 +4140,7 @@ dependencies = [ "rustc_data_structures", "rustc_error_messages", "rustc_hir", + "rustc_hir_id", "rustc_macros", "rustc_serialize", "rustc_span", diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 7fb3533f109..ad6d29e21fc 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -13,7 +13,7 @@ rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } -rustc_hir = { path = "../rustc_hir" } +rustc_hir_id = { path = "../rustc_hir_id" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0a2bfee8b29..a775b70dbee 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -60,7 +60,7 @@ pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, into_diag_arg_using_display, }; use rustc_hashes::Hash128; -use rustc_hir::HirId; +use rustc_hir_id::HirId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; use rustc_lint_defs::{Lint, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 592a9996c8f..1008a3e787d 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -14,6 +14,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_hashes = { path = "../rustc_hashes" } +rustc_hir_id = { path = "../rustc_hir_id" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs deleted file mode 100644 index b48a081d371..00000000000 --- a/compiler/rustc_hir/src/hir_id.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::fmt::{self, Debug}; - -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; -use rustc_macros::{Decodable, Encodable, HashStable_Generic}; -use rustc_span::HashStableContext; -use rustc_span::def_id::DefPathHash; - -use crate::def_id::{CRATE_DEF_ID, DefId, DefIndex, LocalDefId}; - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] -pub struct OwnerId { - pub def_id: LocalDefId, -} - -impl Debug for OwnerId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Example: DefId(0:1 ~ aa[7697]::{use#0}) - Debug::fmt(&self.def_id, f) - } -} - -impl From for HirId { - fn from(owner: OwnerId) -> HirId { - HirId { owner, local_id: ItemLocalId::ZERO } - } -} - -impl From for DefId { - fn from(value: OwnerId) -> Self { - value.to_def_id() - } -} - -impl OwnerId { - #[inline] - pub fn to_def_id(self) -> DefId { - self.def_id.to_def_id() - } -} - -impl rustc_index::Idx for OwnerId { - #[inline] - fn new(idx: usize) -> Self { - OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) } } - } - - #[inline] - fn index(self) -> usize { - self.def_id.local_def_index.as_usize() - } -} - -impl HashStable for OwnerId { - #[inline] - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - self.to_stable_hash_key(hcx).hash_stable(hcx, hasher); - } -} - -impl ToStableHashKey for OwnerId { - type KeyType = DefPathHash; - - #[inline] - fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { - hcx.def_path_hash(self.to_def_id()) - } -} - -/// Uniquely identifies a node in the HIR of the current crate. It is -/// composed of the `owner`, which is the `LocalDefId` of the directly enclosing -/// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"), -/// and the `local_id` which is unique within the given owner. -/// -/// This two-level structure makes for more stable values: One can move an item -/// around within the source code, or add or remove stuff before it, without -/// the `local_id` part of the `HirId` changing, which is a very useful property in -/// incremental compilation where we have to persist things through changes to -/// the code base. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] -#[rustc_pass_by_value] -pub struct HirId { - pub owner: OwnerId, - pub local_id: ItemLocalId, -} - -// To ensure correctness of incremental compilation, -// `HirId` must not implement `Ord` or `PartialOrd`. -// See https://github.com/rust-lang/rust/issues/90317. -impl !Ord for HirId {} -impl !PartialOrd for HirId {} - -impl Debug for HirId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10) - // Don't use debug_tuple to always keep this on one line. - write!(f, "HirId({:?}.{:?})", self.owner, self.local_id) - } -} - -impl HirId { - /// Signal local id which should never be used. - pub const INVALID: HirId = - HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::INVALID }; - - #[inline] - pub fn expect_owner(self) -> OwnerId { - assert_eq!(self.local_id.index(), 0); - self.owner - } - - #[inline] - pub fn as_owner(self) -> Option { - if self.local_id.index() == 0 { Some(self.owner) } else { None } - } - - #[inline] - pub fn is_owner(self) -> bool { - self.local_id.index() == 0 - } - - #[inline] - pub fn make_owner(owner: LocalDefId) -> Self { - Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO } - } -} - -impl fmt::Display for HirId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{self:?}") - } -} - -rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId); -rustc_data_structures::define_id_collections!( - ItemLocalMap, - ItemLocalSet, - ItemLocalMapEntry, - ItemLocalId -); - -rustc_index::newtype_index! { - /// An `ItemLocalId` uniquely identifies something within a given "item-like"; - /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no - /// guarantee that the numerical value of a given `ItemLocalId` corresponds to - /// the node's position within the owning item in any way, but there is a - /// guarantee that the `ItemLocalId`s within an owner occupy a dense range of - /// integers starting at zero, so a mapping that maps all or most nodes within - /// an "item-like" to something else can be implemented by a `Vec` instead of a - /// tree or hash map. - #[derive(HashStable_Generic)] - #[encodable] - #[orderable] - pub struct ItemLocalId {} -} - -impl ItemLocalId { - /// Signal local id which should never be used. - pub const INVALID: ItemLocalId = ItemLocalId::MAX; -} - -impl StableOrd for ItemLocalId { - const CAN_USE_UNSTABLE_SORT: bool = true; - - // `Ord` is implemented as just comparing the ItemLocalId's numerical - // values and these are not changed by (de-)serialization. - const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); -} - -/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`. -pub const CRATE_HIR_ID: HirId = - HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO }; - -pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID }; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index f1212d07ff6..78fc63753a2 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -3,14 +3,11 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html // tidy-alphabetical-start -#![allow(internal_features)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(debug_closure_helpers)] #![feature(exhaustive_patterns)] -#![feature(negative_impls)] #![feature(never_type)] -#![feature(rustc_attrs)] #![feature(variant_count)] #![recursion_limit = "256"] // tidy-alphabetical-end @@ -25,7 +22,7 @@ pub mod definitions; pub mod diagnostic_items; pub use rustc_span::def_id; mod hir; -pub mod hir_id; +pub use rustc_hir_id::{self as hir_id, *}; pub mod intravisit; pub mod lang_items; pub mod lints; @@ -41,7 +38,6 @@ mod tests; #[doc(no_inline)] pub use hir::*; -pub use hir_id::*; pub use lang_items::{LangItem, LanguageItems}; pub use stability::*; pub use stable_hash_impls::HashStableContext; diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs index ecc608d437b..16e8bac3d8a 100644 --- a/compiler/rustc_hir/src/stable_hash_impls.rs +++ b/compiler/rustc_hir/src/stable_hash_impls.rs @@ -5,7 +5,7 @@ use crate::HashIgnoredAttrId; use crate::hir::{ AttributeMap, BodyId, Crate, ForeignItemId, ImplItemId, ItemId, OwnerNodes, TraitItemId, }; -use crate::hir_id::{HirId, ItemLocalId}; +use crate::hir_id::ItemLocalId; use crate::lints::DelayedLints; /// Requirements for a `StableHashingContext` to be used in this crate. @@ -15,25 +15,6 @@ pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStabl fn hash_attr_id(&mut self, id: &HashIgnoredAttrId, hasher: &mut StableHasher); } -impl ToStableHashKey for HirId { - type KeyType = (DefPathHash, ItemLocalId); - - #[inline] - fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) { - let def_path_hash = self.owner.def_id.to_stable_hash_key(hcx); - (def_path_hash, self.local_id) - } -} - -impl ToStableHashKey for ItemLocalId { - type KeyType = ItemLocalId; - - #[inline] - fn to_stable_hash_key(&self, _: &HirCtx) -> ItemLocalId { - *self - } -} - impl ToStableHashKey for BodyId { type KeyType = (DefPathHash, ItemLocalId); diff --git a/compiler/rustc_hir_id/Cargo.toml b/compiler/rustc_hir_id/Cargo.toml new file mode 100644 index 00000000000..c357a4f62d9 --- /dev/null +++ b/compiler/rustc_hir_id/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rustc_hir_id" +version = "0.0.0" +edition = "2024" + +[dependencies] +# tidy-alphabetical-start +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } +# tidy-alphabetical-end diff --git a/compiler/rustc_hir_id/src/lib.rs b/compiler/rustc_hir_id/src/lib.rs new file mode 100644 index 00000000000..17c3e16b467 --- /dev/null +++ b/compiler/rustc_hir_id/src/lib.rs @@ -0,0 +1,194 @@ +#![allow(internal_features)] +#![feature(negative_impls)] +#![feature(rustc_attrs)] + +use std::fmt::{self, Debug}; + +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; +use rustc_macros::{Decodable, Encodable, HashStable_Generic}; +pub use rustc_span::HashStableContext; +use rustc_span::def_id::{CRATE_DEF_ID, DefId, DefIndex, DefPathHash, LocalDefId}; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] +pub struct OwnerId { + pub def_id: LocalDefId, +} + +impl Debug for OwnerId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Example: DefId(0:1 ~ aa[7697]::{use#0}) + Debug::fmt(&self.def_id, f) + } +} + +impl From for HirId { + fn from(owner: OwnerId) -> HirId { + HirId { owner, local_id: ItemLocalId::ZERO } + } +} + +impl From for DefId { + fn from(value: OwnerId) -> Self { + value.to_def_id() + } +} + +impl OwnerId { + #[inline] + pub fn to_def_id(self) -> DefId { + self.def_id.to_def_id() + } +} + +impl rustc_index::Idx for OwnerId { + #[inline] + fn new(idx: usize) -> Self { + OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) } } + } + + #[inline] + fn index(self) -> usize { + self.def_id.local_def_index.as_usize() + } +} + +impl HashStable for OwnerId { + #[inline] + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + self.to_stable_hash_key(hcx).hash_stable(hcx, hasher); + } +} + +impl ToStableHashKey for OwnerId { + type KeyType = DefPathHash; + + #[inline] + fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash { + hcx.def_path_hash(self.to_def_id()) + } +} + +/// Uniquely identifies a node in the HIR of the current crate. It is +/// composed of the `owner`, which is the `LocalDefId` of the directly enclosing +/// `hir::Item`, `hir::TraitItem`, or `hir::ImplItem` (i.e., the closest "item-like"), +/// and the `local_id` which is unique within the given owner. +/// +/// This two-level structure makes for more stable values: One can move an item +/// around within the source code, or add or remove stuff before it, without +/// the `local_id` part of the `HirId` changing, which is a very useful property in +/// incremental compilation where we have to persist things through changes to +/// the code base. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)] +#[rustc_pass_by_value] +pub struct HirId { + pub owner: OwnerId, + pub local_id: ItemLocalId, +} + +// To ensure correctness of incremental compilation, +// `HirId` must not implement `Ord` or `PartialOrd`. +// See https://github.com/rust-lang/rust/issues/90317. +impl !Ord for HirId {} +impl !PartialOrd for HirId {} + +impl Debug for HirId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Example: HirId(DefId(0:1 ~ aa[7697]::{use#0}).10) + // Don't use debug_tuple to always keep this on one line. + write!(f, "HirId({:?}.{:?})", self.owner, self.local_id) + } +} + +impl HirId { + /// Signal local id which should never be used. + pub const INVALID: HirId = + HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::INVALID }; + + #[inline] + pub fn expect_owner(self) -> OwnerId { + assert_eq!(self.local_id.index(), 0); + self.owner + } + + #[inline] + pub fn as_owner(self) -> Option { + if self.local_id.index() == 0 { Some(self.owner) } else { None } + } + + #[inline] + pub fn is_owner(self) -> bool { + self.local_id.index() == 0 + } + + #[inline] + pub fn make_owner(owner: LocalDefId) -> Self { + Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO } + } +} + +impl fmt::Display for HirId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +rustc_data_structures::define_stable_id_collections!(HirIdMap, HirIdSet, HirIdMapEntry, HirId); +rustc_data_structures::define_id_collections!( + ItemLocalMap, + ItemLocalSet, + ItemLocalMapEntry, + ItemLocalId +); + +rustc_index::newtype_index! { + /// An `ItemLocalId` uniquely identifies something within a given "item-like"; + /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no + /// guarantee that the numerical value of a given `ItemLocalId` corresponds to + /// the node's position within the owning item in any way, but there is a + /// guarantee that the `ItemLocalId`s within an owner occupy a dense range of + /// integers starting at zero, so a mapping that maps all or most nodes within + /// an "item-like" to something else can be implemented by a `Vec` instead of a + /// tree or hash map. + #[derive(HashStable_Generic)] + #[encodable] + #[orderable] + pub struct ItemLocalId {} +} + +impl ItemLocalId { + /// Signal local id which should never be used. + pub const INVALID: ItemLocalId = ItemLocalId::MAX; +} + +impl StableOrd for ItemLocalId { + const CAN_USE_UNSTABLE_SORT: bool = true; + + // `Ord` is implemented as just comparing the ItemLocalId's numerical + // values and these are not changed by (de-)serialization. + const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = (); +} + +/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`. +pub const CRATE_HIR_ID: HirId = + HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO }; + +pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID }; + +impl ToStableHashKey for HirId { + type KeyType = (DefPathHash, ItemLocalId); + + #[inline] + fn to_stable_hash_key(&self, hcx: &CTX) -> (DefPathHash, ItemLocalId) { + let def_path_hash = self.owner.def_id.to_stable_hash_key(hcx); + (def_path_hash, self.local_id) + } +} + +impl ToStableHashKey for ItemLocalId { + type KeyType = ItemLocalId; + + #[inline] + fn to_stable_hash_key(&self, _: &CTX) -> ItemLocalId { + *self + } +} diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index 9ab350daf69..a7422d610fc 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -10,6 +10,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_id = { path = "../rustc_hir_id" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 94a290fa5b2..14a95789951 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::{ use rustc_error_messages::{DiagArgValue, DiagMessage, IntoDiagArg, MultiSpan}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefPathHash; -use rustc_hir::{HashStableContext, HirId, ItemLocalId}; +use rustc_hir_id::{HashStableContext, HirId, ItemLocalId}; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::edition::Edition; use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, sym}; @@ -140,7 +140,7 @@ impl LintExpectationId { } } -impl HashStable for LintExpectationId { +impl HashStable for LintExpectationId { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { match self { @@ -158,7 +158,7 @@ impl HashStable for LintExpectationId { } } -impl ToStableHashKey for LintExpectationId { +impl ToStableHashKey for LintExpectationId { type KeyType = (DefPathHash, ItemLocalId, u16, u16); #[inline] -- cgit 1.4.1-3-g733a5