Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hir: Do not introduce dummy type names for extern blocks in def paths #92032

Merged
merged 1 commit into from
Dec 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/rustc_hir/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
}
}

Expand All @@ -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 },
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,8 +1040,8 @@ impl<'tcx> LateContext<'tcx> {
) -> Result<Self::Path, Self::Error> {
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);
}

Expand Down
28 changes: 12 additions & 16 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1740,30 +1740,26 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
) -> Result<Self::Path, Self::Error> {
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);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove the FIXME a couple of lines below, will fix tomorrow.

// 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)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ 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(..)
| ItemKind::Enum(..)
| 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)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_symbol_mangling/src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
) -> Result<Self::Path, Self::Error> {
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);
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,10 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
disambiguated_data: &DisambiguatedDefPathData,
) -> Result<Self::Path, Self::Error> {
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',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this code actually reachable? What will the demangled symbol look like?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's reachable.
Functions and statics in foreign blocks are not mangled, but foreign types are mangled when they are used in any non-foreign symbols.
Something like

extern { type Type; }
fn foo(_arg: &Type) {}


// Uppercase categories are more stable than lowercase ones.
DefPathData::TypeNs(_) => 't',
DefPathData::ValueNs(_) => 'v',
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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())
Comment on lines +169 to +170
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc #91948: How does this interact with that PR, specifically #91948 (comment)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When both PRs are merged this will turn into just elem.data.get_opt_name().

});
let fqn = if let ItemType::Macro = kind {
// Check to see if it is a macro 2.0 or built-in macro
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -45,9 +46,8 @@ impl Module<'hir> {
fn def_id_to_path(tcx: TyCtxt<'_>, did: DefId) -> Vec<String> {
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()
}
Expand Down