From 662e9d00b0ea2137366374e9ac1fdd6ea568a903 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 13 Jul 2023 13:39:19 +0200 Subject: [PATCH 01/10] add test for incomplete alias bound preference --- .../new-solver/alias-bound-preference.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/ui/traits/new-solver/alias-bound-preference.rs diff --git a/tests/ui/traits/new-solver/alias-bound-preference.rs b/tests/ui/traits/new-solver/alias-bound-preference.rs new file mode 100644 index 0000000000000..e4e0f634ef76e --- /dev/null +++ b/tests/ui/traits/new-solver/alias-bound-preference.rs @@ -0,0 +1,39 @@ +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next +// run-pass + +// A test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/45. + +trait Trait { + type Assoc: Into; +} +impl> Trait for T { + type Assoc = T; +} +fn prefer_alias_bound_projection(x: T::Assoc) { + // There are two possible types for `x`: + // - `u32` by using the "alias bound" of `::Assoc` + // - `::Assoc`, i.e. `u16`, by using `impl From for T` + // + // We infer the type of `x` to be `u32` here as it is highly likely + // that this is expected by the user. + let x = x.into(); + assert_eq!(std::mem::size_of_val(&x), 4); +} + +fn impl_trait() -> impl Into { + 0u16 +} + +fn main() { + // There are two possible types for `x`: + // - `u32` by using the "alias bound" of `impl Into` + // - `impl Into`, i.e. `u16`, by using `impl From for T` + // + // We infer the type of `x` to be `u32` here as it is highly likely + // that this is expected by the user. + let x = impl_trait().into(); + assert_eq!(std::mem::size_of_val(&x), 4); + + prefer_alias_bound_projection::(1); +} From fcdff634cfd14ef624f1643a9ca8afc104068fcf Mon Sep 17 00:00:00 2001 From: Arlie Davis Date: Fri, 14 Jul 2023 14:30:06 -0700 Subject: [PATCH 02/10] Use SHA256 by default when targeting MSVC --- compiler/rustc_session/src/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 5be122ffbdeb0..6f4bad9bc1515 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1420,7 +1420,7 @@ pub fn build_session( let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| { if target_cfg.is_like_msvc { - SourceFileHashAlgorithm::Sha1 + SourceFileHashAlgorithm::Sha256 } else { SourceFileHashAlgorithm::Md5 } From 51e1f7a5611c0003398fab18eb339a4178364344 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 15 Jul 2023 10:09:36 +0000 Subject: [PATCH 03/10] Simplify foreign_modules. --- compiler/rustc_metadata/src/foreign_modules.rs | 18 +++++++++++++++--- .../src/rmeta/decoder/cstore_impl.rs | 4 +--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index d1c2f3104d072..b617a1cf53e16 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -1,19 +1,31 @@ +use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::DefKind; +use rustc_hir::def_id::DefId; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::ForeignModule; -pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut modules = Vec::new(); +pub(crate) fn collect( + tcx: TyCtxt<'_>, + LocalCrate: LocalCrate, +) -> FxHashMap { + let mut modules = FxHashMap::default(); + + // We need to collect all the `ForeignMod`, even if they are empty. for id in tcx.hir().items() { if !matches!(tcx.def_kind(id.owner_id), DefKind::ForeignMod) { continue; } + + let def_id = id.owner_id.to_def_id(); let item = tcx.hir().item(id); + if let hir::ItemKind::ForeignMod { items, .. } = item.kind { let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); - modules.push(ForeignModule { foreign_items, def_id: id.owner_id.to_def_id() }); + modules.insert(def_id, ForeignModule { foreign_items, def_id }); } } + modules } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 848535fb39521..324bac69734bc 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -404,9 +404,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { }) }, native_libraries: |tcx, LocalCrate| native_libs::collect(tcx), - foreign_modules: |tcx, LocalCrate| { - foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect() - }, + foreign_modules: foreign_modules::collect, // Returns a map from a sufficiently visible external item (i.e., an // external item that is visible from at least one local module) to a From fdc93f307ffb28390aeab9be221a5e9e90517c3a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 15 Jul 2023 10:17:37 +0000 Subject: [PATCH 04/10] Do not fetch HIR in native_libs. --- .../rustc_metadata/src/foreign_modules.rs | 13 ++- compiler/rustc_metadata/src/native_libs.rs | 80 ++++++++----------- .../src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_session/src/cstore.rs | 2 + 5 files changed, 43 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index b617a1cf53e16..154eb684f1197 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; @@ -6,11 +6,8 @@ use rustc_middle::query::LocalCrate; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::ForeignModule; -pub(crate) fn collect( - tcx: TyCtxt<'_>, - LocalCrate: LocalCrate, -) -> FxHashMap { - let mut modules = FxHashMap::default(); +pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> FxIndexMap { + let mut modules = FxIndexMap::default(); // We need to collect all the `ForeignMod`, even if they are empty. for id in tcx.hir().items() { @@ -21,9 +18,9 @@ pub(crate) fn collect( let def_id = id.owner_id.to_def_id(); let item = tcx.hir().item(id); - if let hir::ItemKind::ForeignMod { items, .. } = item.kind { + if let hir::ItemKind::ForeignMod { abi, items } = item.kind { let foreign_items = items.iter().map(|it| it.id.owner_id.to_def_id()).collect(); - modules.insert(def_id, ForeignModule { foreign_items, def_id }); + modules.insert(def_id, ForeignModule { def_id, abi, foreign_items }); } } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 9e0bf81d58dc8..ca5043cc26339 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -1,15 +1,17 @@ use rustc_ast::{NestedMetaItem, CRATE_NODE_ID}; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; -use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_session::config::CrateType; -use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType}; +use rustc_session::cstore::{ + DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType, +}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; use rustc_session::Session; +use rustc_span::def_id::{DefId, LOCAL_CRATE}; use rustc_span::symbol::{sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -66,10 +68,12 @@ fn find_bundled_library( None } -pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec { +pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec { let mut collector = Collector { tcx, libs: Vec::new() }; - for id in tcx.hir().items() { - collector.process_item(id); + if tcx.sess.opts.unstable_opts.link_directives { + for module in tcx.foreign_modules(LOCAL_CRATE).values() { + collector.process_module(module); + } } collector.process_command_line(); collector.libs @@ -88,29 +92,20 @@ struct Collector<'tcx> { } impl<'tcx> Collector<'tcx> { - fn process_item(&mut self, id: rustc_hir::ItemId) { - if !matches!(self.tcx.def_kind(id.owner_id), DefKind::ForeignMod) { - return; - } + fn process_module(&mut self, module: &ForeignModule) { + let ForeignModule { def_id, abi, ref foreign_items } = *module; + let def_id = def_id.expect_local(); - let it = self.tcx.hir().item(id); - let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else { - return; - }; + let sess = self.tcx.sess; if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) { return; } // Process all of the #[link(..)]-style arguments - let sess = self.tcx.sess; let features = self.tcx.features(); - if !sess.opts.unstable_opts.link_directives { - return; - } - - for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) { + for m in self.tcx.get_attrs(def_id, sym::link) { let Some(items) = m.meta_item_list() else { continue; }; @@ -340,9 +335,9 @@ impl<'tcx> Collector<'tcx> { if name.as_str().contains('\0') { sess.emit_err(errors::RawDylibNoNul { span: name_span }); } - foreign_mod_items + foreign_items .iter() - .map(|child_item| { + .map(|&child_item| { self.build_dll_import( abi, import_name_type.map(|(import_name_type, _)| import_name_type), @@ -352,21 +347,12 @@ impl<'tcx> Collector<'tcx> { .collect() } _ => { - for child_item in foreign_mod_items { - if self.tcx.def_kind(child_item.id.owner_id).has_codegen_attrs() - && self - .tcx - .codegen_fn_attrs(child_item.id.owner_id) - .link_ordinal - .is_some() + for &child_item in foreign_items { + if self.tcx.def_kind(child_item).has_codegen_attrs() + && self.tcx.codegen_fn_attrs(child_item).link_ordinal.is_some() { - let link_ordinal_attr = self - .tcx - .hir() - .attrs(child_item.id.owner_id.into()) - .iter() - .find(|a| a.has_name(sym::link_ordinal)) - .unwrap(); + let link_ordinal_attr = + self.tcx.get_attr(child_item, sym::link_ordinal).unwrap(); sess.emit_err(errors::LinkOrdinalRawDylib { span: link_ordinal_attr.span, }); @@ -384,7 +370,7 @@ impl<'tcx> Collector<'tcx> { filename, kind, cfg, - foreign_module: Some(it.owner_id.to_def_id()), + foreign_module: Some(def_id.to_def_id()), verbatim, dll_imports, }); @@ -476,10 +462,10 @@ impl<'tcx> Collector<'tcx> { } } - fn i686_arg_list_size(&self, item: &hir::ForeignItemRef) -> usize { + fn i686_arg_list_size(&self, item: DefId) -> usize { let argument_types: &List> = self.tcx.erase_late_bound_regions( self.tcx - .type_of(item.id.owner_id) + .type_of(item) .instantiate_identity() .fn_sig(self.tcx) .inputs() @@ -505,8 +491,10 @@ impl<'tcx> Collector<'tcx> { &self, abi: Abi, import_name_type: Option, - item: &hir::ForeignItemRef, + item: DefId, ) -> DllImport { + let span = self.tcx.def_span(item); + let calling_convention = if self.tcx.sess.target.arch == "x86" { match abi { Abi::C { .. } | Abi::Cdecl { .. } => DllCallingConvention::C, @@ -520,29 +508,29 @@ impl<'tcx> Collector<'tcx> { DllCallingConvention::Vectorcall(self.i686_arg_list_size(item)) } _ => { - self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span: item.span }); + self.tcx.sess.emit_fatal(errors::UnsupportedAbiI686 { span }); } } } else { match abi { Abi::C { .. } | Abi::Win64 { .. } | Abi::System { .. } => DllCallingConvention::C, _ => { - self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span: item.span }); + self.tcx.sess.emit_fatal(errors::UnsupportedAbi { span }); } } }; - let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item.id.owner_id); + let codegen_fn_attrs = self.tcx.codegen_fn_attrs(item); let import_name_type = codegen_fn_attrs .link_ordinal .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord))); DllImport { - name: codegen_fn_attrs.link_name.unwrap_or(item.ident.name), + name: codegen_fn_attrs.link_name.unwrap_or(self.tcx.item_name(item)), import_name_type, calling_convention, - span: item.span, - is_fn: self.tcx.def_kind(item.id.owner_id).is_fn_like(), + span, + is_fn: self.tcx.def_kind(item).is_fn_like(), } } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 324bac69734bc..a8815ee0908d6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -403,7 +403,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { .contains(&id) }) }, - native_libraries: |tcx, LocalCrate| native_libs::collect(tcx), + native_libraries: native_libs::collect, foreign_modules: foreign_modules::collect, // Returns a map from a sufficiently visible external item (i.e., an diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 45fa82ba68ad5..a8c0751e1f9f0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,7 +1579,7 @@ rustc_queries! { } /// Returns a list of all `extern` blocks of a crate. - query foreign_modules(_: CrateNum) -> &'tcx FxHashMap { + query foreign_modules(_: CrateNum) -> &'tcx FxIndexMap { arena_cache desc { "looking up the foreign modules of a linked crate" } separate_provide_extern diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index dc475e8c6d57c..c53a355b533ea 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -13,6 +13,7 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::symbol::Symbol; use rustc_span::Span; +use rustc_target::spec::abi::Abi; use rustc_target::spec::Target; use std::any::Any; @@ -147,6 +148,7 @@ pub enum DllCallingConvention { pub struct ForeignModule { pub foreign_items: Vec, pub def_id: DefId, + pub abi: Abi, } #[derive(Copy, Clone, Debug, HashStable_Generic)] From 6fb4ce9f88ee0651a7a05f512a155de21f395e11 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 16 Jul 2023 23:22:16 +0200 Subject: [PATCH 05/10] Fix invalid display of inlined re-export --- src/librustdoc/clean/mod.rs | 19 +++++++++++++++--- src/librustdoc/visit_ast.rs | 40 ++++++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2d00c53951fef..56545983d425e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -90,6 +90,19 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); + items.extend(doc.inlined_foreigns.values().flat_map(|(res, renamed, 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); + match import.kind { + hir::ItemKind::Use(path, kind) => { + let hir::UsePath { segments, span, .. } = *path; + let path = hir::Path { segments, res: *res, span }; + clean_use_statement_inner(import, name, &path, kind, cx, &mut Default::default()) + } + _ => unreachable!(), + } + })); 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 { @@ -2652,9 +2665,6 @@ fn clean_use_statement<'tcx>( let mut items = Vec::new(); let hir::UsePath { segments, ref res, span } = *path; for &res in res { - if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res { - continue; - } let path = hir::Path { segments, res, span }; items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names)); } @@ -2669,6 +2679,9 @@ fn clean_use_statement_inner<'tcx>( cx: &mut DocContext<'tcx>, inlined_names: &mut FxHashSet<(ItemType, Symbol)>, ) -> Vec { + if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = path.res { + return Vec::new(); + } // We need this comparison because some imports (for std types for example) // are "inserted" as well but directly by the compiler and they should not be // taken into account. diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 265123ddf6c8b..cee3995eff411 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -35,6 +35,9 @@ pub(crate) struct Module<'hir> { (LocalDefId, Option), (&'hir hir::Item<'hir>, Option, Option), >, + /// Same as for `items`. + pub(crate) inlined_foreigns: + FxIndexMap<(DefId, Option), (Res, Option, LocalDefId)>, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, } @@ -54,6 +57,7 @@ impl Module<'_> { import_id, mods: Vec::new(), items: FxIndexMap::default(), + inlined_foreigns: FxIndexMap::default(), foreigns: Vec::new(), } } @@ -272,21 +276,30 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } - // For cross-crate impl inlining we need to know whether items are - // reachable in documentation -- a previously unreachable item can be - // made reachable by cross-crate inlining which we're checking here. - // (this is done here because we need to know this upfront). - if !ori_res_did.is_local() && !is_no_inline { - crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did); - return false; - } - + let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did); let Some(res_did) = ori_res_did.as_local() else { - return false; + // For cross-crate impl inlining we need to know whether items are + // reachable in documentation -- a previously unreachable item can be + // made reachable by cross-crate inlining which we're checking here. + // (this is done here because we need to know this upfront). + crate::visit_lib::lib_embargo_visit_item(self.cx, ori_res_did); + if is_hidden { + return false; + } + // We store inlined foreign items otherwise, it'd mean that the `use` item would be kept + // around. It's not a problem unless this `use` imports both a local AND a foreign item. + // If a local item is inlined, its `use` is not supposed to still be around in `clean`, + // which would make appear the `use` in the generated documentation like the local item + // was not inlined even though it actually was. + self.modules + .last_mut() + .unwrap() + .inlined_foreigns + .insert((ori_res_did, renamed), (res, renamed, def_id)); + return true; }; let is_private = !self.cx.cache.effective_visibilities.is_directly_public(tcx, ori_res_did); - let is_hidden = !document_hidden && tcx.is_doc_hidden(ori_res_did); let item = tcx.hir().get_by_def_id(res_did); if !please_inline { @@ -314,7 +327,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { return false; } - let inlined = match tcx.hir().get_by_def_id(res_did) { + let inlined = match item { // Bang macros are handled a bit on their because of how they are handled by the // compiler. If they have `#[doc(hidden)]` and the re-export doesn't have // `#[doc(inline)]`, then we don't inline it. @@ -346,7 +359,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; self.view_item_stack.remove(&res_did); if inlined { - self.cx.cache.inlined_items.insert(res_did.to_def_id()); + self.cx.cache.inlined_items.insert(ori_res_did); } inlined } @@ -483,7 +496,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { continue; } } - self.add_to_current_mod(item, renamed, import_id); } } From c845a53aa23c1252f1cc15528799d652512b877e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 16 Jul 2023 15:54:23 +0200 Subject: [PATCH 06/10] Add regression test for #105735 --- .../issue-105735-overlapping-reexport-2.rs | 25 +++++++++++++++++++ .../issue-105735-overlapping-reexport.rs | 21 ++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tests/rustdoc/issue-105735-overlapping-reexport-2.rs create mode 100644 tests/rustdoc/issue-105735-overlapping-reexport.rs diff --git a/tests/rustdoc/issue-105735-overlapping-reexport-2.rs b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs new file mode 100644 index 0000000000000..9108248394894 --- /dev/null +++ b/tests/rustdoc/issue-105735-overlapping-reexport-2.rs @@ -0,0 +1,25 @@ +// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. + +#![crate_name = "foo"] +#![no_std] + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]/a[@class="type"]' 'AtomicU8' +// @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' +// We also ensure we don't have another item displayed. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Type Definitions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' + +mod other { + pub type AtomicU8 = (); +} + +mod thing { + pub use crate::other::AtomicU8; + + #[allow(non_upper_case_globals)] + pub const AtomicU8: () = (); +} + +pub use crate::thing::AtomicU8; diff --git a/tests/rustdoc/issue-105735-overlapping-reexport.rs b/tests/rustdoc/issue-105735-overlapping-reexport.rs new file mode 100644 index 0000000000000..50f2450b90a0b --- /dev/null +++ b/tests/rustdoc/issue-105735-overlapping-reexport.rs @@ -0,0 +1,21 @@ +// Regression test to ensure that both `AtomicU8` items are displayed but not the re-export. + +#![crate_name = "foo"] +#![no_std] + +// @has 'foo/index.html' +// @has - '//*[@class="item-name"]/a[@class="struct"]' 'AtomicU8' +// @has - '//*[@class="item-name"]/a[@class="constant"]' 'AtomicU8' +// We also ensure we don't have another item displayed. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 2 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' + +mod thing { + pub use core::sync::atomic::AtomicU8; + + #[allow(non_upper_case_globals)] + pub const AtomicU8: () = (); +} + +pub use crate::thing::AtomicU8; From afec6d242bf308139503e4051fc4251f785b377a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 17 Jul 2023 20:33:54 +0200 Subject: [PATCH 07/10] Remove unneeded `Option` in `foreign_items` --- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/visit_ast.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 56545983d425e..d14953f1bb786 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); - items.extend(doc.inlined_foreigns.values().flat_map(|(res, renamed, local_import_id)| { + 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); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index cee3995eff411..66737a0152158 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -36,8 +36,7 @@ pub(crate) struct Module<'hir> { (&'hir hir::Item<'hir>, Option, Option), >, /// Same as for `items`. - pub(crate) inlined_foreigns: - FxIndexMap<(DefId, Option), (Res, Option, LocalDefId)>, + pub(crate) inlined_foreigns: FxIndexMap<(DefId, Option), (Res, LocalDefId)>, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option)>, } @@ -295,7 +294,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .last_mut() .unwrap() .inlined_foreigns - .insert((ori_res_did, renamed), (res, renamed, def_id)); + .insert((ori_res_did, renamed), (res, def_id)); return true; }; From 09743b9ebfc7d2cc343b28da8c4e946cc8b8c65c Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 17 Jul 2023 07:38:37 +0000 Subject: [PATCH 08/10] Bless ui tests. --- tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr | 2 +- tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr index 5101084054882..dfd24566953fb 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr @@ -2,7 +2,7 @@ error: multiple declarations of external function `f` from library `foo.dll` hav --> $DIR/multiple-declarations.rs:13:9 | LL | fn f(x: i32); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr index f8265ae691948..f69275a01253f 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr @@ -2,7 +2,7 @@ error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture --> $DIR/unsupported-abi.rs:6:5 | LL | fn f(x: i32); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to previous error From c6f0a7c3c3070f90a9e9dcc3e5a91d1183afc978 Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Wed, 19 Jul 2023 11:19:33 +0800 Subject: [PATCH 09/10] avoid clone path prefix when lowering to hir Signed-off-by: SparrowLii --- compiler/rustc_ast_lowering/src/item.rs | 11 ----------- compiler/rustc_ast_lowering/src/lib.rs | 10 ---------- 2 files changed, 21 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index ab68436c0939d..d3fc76db1fa77 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -551,17 +551,6 @@ impl<'hir> LoweringContext<'_, 'hir> { for &(ref use_tree, id) in trees { let new_hir_id = self.local_def_id(id); - let mut prefix = prefix.clone(); - - // Give the segments new node-ids since they are being cloned. - for seg in &mut prefix.segments { - // Give the cloned segment the same resolution information - // as the old one (this is needed for stability checking). - let new_id = self.next_node_id(); - self.resolver.clone_res(seg.id, new_id); - seg.id = new_id; - } - // Each `use` import is an item and thus are owners of the // names in the path. Up to this point the nested import is // the current owner, since we want each desugared import to diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 429e62c4a1c63..5635770674568 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -148,10 +148,6 @@ trait ResolverAstLoweringExt { fn legacy_const_generic_args(&self, expr: &Expr) -> Option>; fn get_partial_res(&self, id: NodeId) -> Option; fn get_import_res(&self, id: NodeId) -> PerNS>>; - // Clones the resolution (if any) on 'source' and applies it - // to 'target'. Used when desugaring a `UseTreeKind::Nested` to - // multiple `UseTreeKind::Simple`s - fn clone_res(&mut self, source: NodeId, target: NodeId); fn get_label_res(&self, id: NodeId) -> Option; fn get_lifetime_res(&self, id: NodeId) -> Option; fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>; @@ -184,12 +180,6 @@ impl ResolverAstLoweringExt for ResolverAstLowering { None } - fn clone_res(&mut self, source: NodeId, target: NodeId) { - if let Some(res) = self.partial_res_map.get(&source) { - self.partial_res_map.insert(target, *res); - } - } - /// Obtains resolution for a `NodeId` with a single resolution. fn get_partial_res(&self, id: NodeId) -> Option { self.partial_res_map.get(&id).copied() From 0377945157da71c05ba52edca2de6f071212338c Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Wed, 19 Jul 2023 16:48:33 +0800 Subject: [PATCH 10/10] add comment for lower_use_tree Signed-off-by: SparrowLii --- compiler/rustc_ast_lowering/src/item.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d3fc76db1fa77..2f58f566c81c3 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -559,6 +559,9 @@ impl<'hir> LoweringContext<'_, 'hir> { self.with_hir_id_owner(id, |this| { let mut ident = *ident; + // `prefix` is lowered multiple times, but in different HIR owners. + // So each segment gets renewed `HirId` with the same + // `ItemLocalId` and the new owner. (See `lower_node_id`) let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs); if let Some(attrs) = attrs {