From 0d61852cc5e3c9c441e861acd31a1fc72f584c5b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 17 Dec 2021 16:45:15 +0800 Subject: [PATCH] hir: Do not introduce dummy type names for `extern` blocks in def paths Use a separate nameless `DefPathData` variant instead --- compiler/rustc_hir/src/definitions.rs | 7 ++++- compiler/rustc_lint/src/context.rs | 4 +-- compiler/rustc_middle/src/ty/print/pretty.rs | 28 +++++++++----------- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 4 +-- compiler/rustc_symbol_mangling/src/v0.rs | 4 +++ src/librustdoc/clean/inline.rs | 6 ++--- src/librustdoc/visit_ast.rs | 6 ++--- 8 files changed, 33 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index ca29351455e62..40071c6df8cca 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -267,6 +267,8 @@ pub enum DefPathData { // Different kinds of items and item-like things: /// An impl. Impl, + /// An `extern` block. + ForeignMod, /// Something in the type namespace. TypeNs(Symbol), /// Something in the value namespace. @@ -469,7 +471,9 @@ impl DefPathData { match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - Impl | CrateRoot | Misc | ClosureExpr | Ctor | AnonConst | ImplTrait => None, + Impl | ForeignMod | CrateRoot | Misc | ClosureExpr | Ctor | AnonConst | ImplTrait => { + None + } } } @@ -482,6 +486,7 @@ impl DefPathData { // Note that this does not show up in user print-outs. CrateRoot => DefPathDataName::Anon { namespace: kw::Crate }, Impl => DefPathDataName::Anon { namespace: kw::Impl }, + ForeignMod => DefPathDataName::Anon { namespace: kw::Extern }, Misc => DefPathDataName::Anon { namespace: sym::misc }, ClosureExpr => DefPathDataName::Anon { namespace: sym::closure }, Ctor => DefPathDataName::Anon { namespace: sym::constructor }, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 71db58f2d8bae..313a1cc208633 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1040,8 +1040,8 @@ impl<'tcx> LateContext<'tcx> { ) -> Result { let mut path = print_prefix(self)?; - // Skip `::{{constructor}}` on tuple/unit structs. - if let DefPathData::Ctor = disambiguated_data.data { + // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. + if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data { return Ok(path); } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 175295b3199e8..b3b8183d313f3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1740,30 +1740,26 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { ) -> Result { self = print_prefix(self)?; - // Skip `::{{constructor}}` on tuple/unit structs. - if let DefPathData::Ctor = disambiguated_data.data { + // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. + if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data { return Ok(self); } - // FIXME(eddyb) `name` should never be empty, but it - // currently is for `extern { ... }` "foreign modules". let name = disambiguated_data.data.name(); - if name != DefPathDataName::Named(kw::Empty) { - if !self.empty_path { - write!(self, "::")?; - } + if !self.empty_path { + write!(self, "::")?; + } - if let DefPathDataName::Named(name) = name { - if Ident::with_dummy_span(name).is_raw_guess() { - write!(self, "r#")?; - } + if let DefPathDataName::Named(name) = name { + if Ident::with_dummy_span(name).is_raw_guess() { + write!(self, "r#")?; } + } - let verbose = self.tcx.sess.verbose(); - disambiguated_data.fmt_maybe_verbose(&mut self, verbose)?; + let verbose = self.tcx.sess.verbose(); + disambiguated_data.fmt_maybe_verbose(&mut self, verbose)?; - self.empty_path = false; - } + self.empty_path = false; Ok(self) } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 391baa85c61db..688b7b1a8c6d2 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -92,6 +92,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { // information we encapsulate into, the better let def_data = match &i.kind { ItemKind::Impl { .. } => DefPathData::Impl, + ItemKind::ForeignMod(..) => DefPathData::ForeignMod, ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) @@ -99,7 +100,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::ExternCrate(..) - | ItemKind::ForeignMod(..) | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { DefPathData::ValueNs(i.ident.name) diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index cdea84a8d60f7..0232aace6d78c 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -311,8 +311,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> { ) -> Result { self = print_prefix(self)?; - // Skip `::{{constructor}}` on tuple/unit structs. - if let DefPathData::Ctor = disambiguated_data.data { + // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs. + if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data { return Ok(self); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 167ff758f3480..ea6366c407e21 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -771,6 +771,10 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let ns = match disambiguated_data.data { + // FIXME: It shouldn't be necessary to add anything for extern block segments, + // but we add 't' for backward compatibility. + DefPathData::ForeignMod => 't', + // Uppercase categories are more stable than lowercase ones. DefPathData::TypeNs(_) => 't', DefPathData::ValueNs(_) => 'v', diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 39544fa843de8..57621f4f18cfe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::definitions::DefPathData; use rustc_hir::Mutability; use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt}; @@ -165,9 +166,8 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) let crate_name = cx.tcx.crate_name(did.krate).to_string(); let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| { - // extern blocks have an empty name - let s = elem.data.to_string(); - if !s.is_empty() { Some(s) } else { None } + // Filter out extern blocks + (elem.data != DefPathData::ForeignMod).then(|| elem.data.to_string()) }); let fqn = if let ItemType::Macro = kind { // Check to see if it is a macro 2.0 or built-in macro diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index a18bd48d72bc4..ea7372761ba31 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -5,6 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::definitions::DefPathData; use rustc_hir::Node; use rustc_hir::CRATE_HIR_ID; use rustc_middle::middle::privacy::AccessLevel; @@ -45,9 +46,8 @@ impl Module<'hir> { fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec { let crate_name = tcx.crate_name(did.krate).to_string(); let relative = tcx.def_path(did).data.into_iter().filter_map(|elem| { - // extern blocks have an empty name - let s = elem.data.to_string(); - if !s.is_empty() { Some(s) } else { None } + // Filter out extern blocks + (elem.data != DefPathData::ForeignMod).then(|| elem.data.to_string()) }); std::iter::once(crate_name).chain(relative).collect() }