From f5a9f6fb7eccc1545ff871c6f15b8a2d49df2efc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 29 Mar 2023 22:15:38 +0400 Subject: [PATCH] rustc_metadata: Filter encoded data more aggressively using `DefKind` --- .../rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 24 ++- compiler/rustc_metadata/src/rmeta/encoder.rs | 139 ++++++++++++++++-- src/librustdoc/clean/types.rs | 2 +- .../associated-types-in-ambiguous-context.rs | 2 + ...sociated-types-in-ambiguous-context.stderr | 21 ++- 6 files changed, 165 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index acca3fa2641..37c894348cd 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2580,7 +2580,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.all_impls(trait_def_id) .filter(|impl_def_id| { // Consider only accessible traits - tcx.visibility(*impl_def_id).is_accessible_from(self.item_def_id(), tcx) + tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx) && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative }) .filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id)) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index f9d32ffceef..77308212c32 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -749,6 +749,10 @@ impl CrateRoot { } impl<'a, 'tcx> CrateMetadataRef<'a> { + fn missing(self, descr: &str, id: DefIndex) -> ! { + bug!("missing `{descr}` for {:?}", self.local_def_id(id)) + } + fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro { // DefIndex's in root.proc_macro_data have a one-to-one correspondence // with items in 'raw_proc_macros'. @@ -782,8 +786,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option { let name = self.opt_item_name(item_index)?; - let span = - self.root.tables.def_ident_span.get(self, item_index).unwrap().decode((self, sess)); + let span = self + .root + .tables + .def_ident_span + .get(self, item_index) + .unwrap_or_else(|| self.missing("def_ident_span", item_index)) + .decode((self, sess)); Some(Ident::new(name, span)) } @@ -812,7 +821,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .def_span .get(self, index) - .unwrap_or_else(|| panic!("Missing span for {index:?}")) + .unwrap_or_else(|| self.missing("def_span", index)) .decode((self, sess)) } @@ -924,7 +933,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .visibility .get(self, id) - .unwrap() + .unwrap_or_else(|| self.missing("visibility", id)) .decode(self) .map_id(|index| self.local_def_id(index)) } @@ -934,7 +943,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId { - self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess)) + self.root + .tables + .expn_that_defined + .get(self, id) + .unwrap_or_else(|| self.missing("expn_that_defined", id)) + .decode((self, sess)) } fn get_debugger_visualizers(self) -> Vec { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1b2c4b53de5..77ec03165fb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -811,6 +811,117 @@ fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool { should_encode } +fn should_encode_span(def_kind: DefKind) -> bool { + match def_kind { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::Fn + | DefKind::Const + | DefKind::Static(_) + | DefKind::Ctor(..) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::Field + | DefKind::Impl { .. } + | DefKind::Closure + | DefKind::Generator => true, + DefKind::ConstParam + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::ImplTraitPlaceholder + | DefKind::LifetimeParam + | DefKind::GlobalAsm => false, + } +} + +fn should_encode_attrs(def_kind: DefKind) -> bool { + match def_kind { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::Fn + | DefKind::Const + | DefKind::Static(_) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::Field + | DefKind::Impl { .. } => true, + DefKind::TyParam + | DefKind::ConstParam + | DefKind::Ctor(..) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Closure + | DefKind::Generator => false, + } +} + +fn should_encode_expn_that_defined(def_kind: DefKind) -> bool { + match def_kind { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::Impl { .. } => true, + DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::Fn + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(_) + | DefKind::Ctor(..) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Closure + | DefKind::Generator => false, + } +} + fn should_encode_visibility(def_kind: DefKind) -> bool { match def_kind { DefKind::Mod @@ -830,18 +941,18 @@ fn should_encode_visibility(def_kind: DefKind) -> bool { | DefKind::AssocFn | DefKind::AssocConst | DefKind::Macro(..) - | DefKind::Use - | DefKind::ForeignMod - | DefKind::OpaqueTy - | DefKind::ImplTraitPlaceholder - | DefKind::Impl { .. } | DefKind::Field => true, - DefKind::TyParam + DefKind::Use + | DefKind::ForeignMod + | DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam | DefKind::AnonConst | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm + | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator | DefKind::ExternCrate => false, @@ -1160,11 +1271,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_kind = tcx.opt_def_kind(local_id); let Some(def_kind) = def_kind else { continue }; self.tables.opt_def_kind.set_some(def_id.index, def_kind); - let def_span = tcx.def_span(local_id); - record!(self.tables.def_span[def_id] <- def_span); - self.encode_attrs(local_id); - record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); - if let Some(ident_span) = tcx.def_ident_span(def_id) { + if should_encode_span(def_kind) { + let def_span = tcx.def_span(local_id); + record!(self.tables.def_span[def_id] <- def_span); + } + if should_encode_attrs(def_kind) { + self.encode_attrs(local_id); + } + if should_encode_expn_that_defined(def_kind) { + record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id)); + } + if should_encode_span(def_kind) && let Some(ident_span) = tcx.def_ident_span(def_id) { record!(self.tables.def_ident_span[def_id] <- ident_span); } if def_kind.has_codegen_attrs() { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a37d4f31643..bbf4503f74e 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -687,7 +687,7 @@ impl Item { return None; } // Variants always inherit visibility - VariantItem(..) => return None, + VariantItem(..) | ImplItem(..) => return None, // Trait items inherit the trait's visibility AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..) | TyMethodItem(..) | MethodItem(..) => { diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs index 51b53908f98..5d6b1b59181 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs @@ -1,3 +1,5 @@ +// normalize-stderr-test: "and \d+ other candidates" -> "and N other candidates" + trait Get { type Value; fn get(&self) -> ::Value; diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index 00856b55df5..1ff6fd4b821 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -1,5 +1,5 @@ error[E0223]: ambiguous associated type - --> $DIR/associated-types-in-ambiguous-context.rs:6:36 + --> $DIR/associated-types-in-ambiguous-context.rs:8:36 | LL | fn get(x: T, y: U) -> Get::Value {} | ^^^^^^^^^^ @@ -10,30 +10,37 @@ LL | fn get(x: T, y: U) -> ::Value {} | ~~~~~~~~~~~~~~~~~~~~~~~ error[E0223]: ambiguous associated type - --> $DIR/associated-types-in-ambiguous-context.rs:20:17 + --> $DIR/associated-types-in-ambiguous-context.rs:22:17 | LL | trait Foo where Foo::Assoc: Bar { | ^^^^^^^^^^ help: use the fully-qualified path: `::Assoc` error[E0223]: ambiguous associated type - --> $DIR/associated-types-in-ambiguous-context.rs:25:10 + --> $DIR/associated-types-in-ambiguous-context.rs:27:10 | LL | type X = std::ops::Deref::Target; | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: if there were a type named `Example` that implemented `Deref`, you could use the fully-qualified path +help: use the fully-qualified path | -LL | type X = ::Target; +LL | type X = ::Target; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | type X = as Deref>::Target; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | type X = as Deref>::Target; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | type X = ::Target; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + and N other candidates error[E0223]: ambiguous associated type - --> $DIR/associated-types-in-ambiguous-context.rs:11:23 + --> $DIR/associated-types-in-ambiguous-context.rs:13:23 | LL | fn grab(&self) -> Grab::Value; | ^^^^^^^^^^^ help: use the fully-qualified path: `::Value` error[E0223]: ambiguous associated type - --> $DIR/associated-types-in-ambiguous-context.rs:14:22 + --> $DIR/associated-types-in-ambiguous-context.rs:16:22 | LL | fn get(&self) -> Get::Value; | ^^^^^^^^^^