rustc_metadata: Filter encoded data more aggressively using DefKind

This commit is contained in:
Vadim Petrochenkov 2023-03-29 22:15:38 +04:00
parent 9dd27b31ba
commit f5a9f6fb7e
6 changed files with 165 additions and 25 deletions

View File

@ -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))

View File

@ -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<Ident> {
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<rustc_span::DebuggerVisualizerFile> {

View File

@ -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() {

View File

@ -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(..) => {

View File

@ -1,3 +1,5 @@
// normalize-stderr-test: "and \d+ other candidates" -> "and N other candidates"
trait Get {
type Value;
fn get(&self) -> <Self as Get>::Value;

View File

@ -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<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
| ^^^^^^^^^^
@ -10,30 +10,37 @@ LL | fn get<T:Get,U:Get>(x: T, y: U) -> <Example as Get>::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: `<Self as Foo>::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 = <Example as Deref>::Target;
LL | type X = <CString as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <IoSlice<'_> as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <IoSliceMut<'_> as Deref>::Target;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | type X = <OsString as Deref>::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: `<Self as Grab>::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;
| ^^^^^^^^^^