resolve: Cleanup visibility resolution in enums and traits
This commit is contained in:
parent
07194ffcd2
commit
b4b6b62e70
1 changed files with 44 additions and 65 deletions
|
@ -258,16 +258,16 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
|
Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
|
||||||
}
|
}
|
||||||
ast::VisibilityKind::Inherited => {
|
ast::VisibilityKind::Inherited => {
|
||||||
if matches!(self.parent_scope.module.kind, ModuleKind::Def(DefKind::Enum, _, _)) {
|
Ok(match self.parent_scope.module.kind {
|
||||||
// Any inherited visibility resolved directly inside an enum
|
// Any inherited visibility resolved directly inside an enum or trait
|
||||||
// (e.g. variants or fields) inherits from the visibility of the enum.
|
// (i.e. variants, fields, and trait items) inherits from the visibility
|
||||||
let parent_enum = self.parent_scope.module.def_id().unwrap().expect_local();
|
// of the enum or trait.
|
||||||
Ok(self.r.visibilities[&parent_enum])
|
ModuleKind::Def(DefKind::Enum | DefKind::Trait, def_id, _) => {
|
||||||
} else {
|
self.r.visibilities[&def_id.expect_local()]
|
||||||
// If it's not in an enum, its visibility is restricted to the `mod` item
|
}
|
||||||
// that it's defined in.
|
// Otherwise, the visibility is restricted to the nearest parent `mod` item.
|
||||||
Ok(ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod))
|
_ => ty::Visibility::Restricted(self.parent_scope.module.nearest_parent_mod),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
ast::VisibilityKind::Restricted { ref path, id, .. } => {
|
ast::VisibilityKind::Restricted { ref path, id, .. } => {
|
||||||
// For visibilities we are not ready to provide correct implementation of "uniform
|
// For visibilities we are not ready to provide correct implementation of "uniform
|
||||||
|
@ -1365,60 +1365,45 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vis = self.resolve_visibility(&item.vis);
|
||||||
let local_def_id = self.r.local_def_id(item.id);
|
let local_def_id = self.r.local_def_id(item.id);
|
||||||
let def_id = local_def_id.to_def_id();
|
let def_id = local_def_id.to_def_id();
|
||||||
let vis = match ctxt {
|
|
||||||
AssocCtxt::Trait => {
|
|
||||||
let (def_kind, ns) = match item.kind {
|
|
||||||
AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS),
|
|
||||||
AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) => {
|
|
||||||
if sig.decl.has_self() {
|
|
||||||
self.r.has_self.insert(def_id);
|
|
||||||
}
|
|
||||||
(DefKind::AssocFn, ValueNS)
|
|
||||||
}
|
|
||||||
AssocItemKind::TyAlias(..) => (DefKind::AssocTy, TypeNS),
|
|
||||||
AssocItemKind::MacCall(_) => bug!(), // handled above
|
|
||||||
};
|
|
||||||
|
|
||||||
let parent = self.parent_scope.module;
|
if !(ctxt == AssocCtxt::Impl
|
||||||
let expansion = self.parent_scope.expansion;
|
&& matches!(item.vis.kind, ast::VisibilityKind::Inherited)
|
||||||
let res = Res::Def(def_kind, def_id);
|
&& self
|
||||||
// Trait item visibility is inherited from its trait when not specified explicitly.
|
.r
|
||||||
let vis = match &item.vis.kind {
|
.trait_impl_items
|
||||||
ast::VisibilityKind::Inherited => {
|
.contains(&ty::DefIdTree::parent(&*self.r, def_id).unwrap().expect_local()))
|
||||||
self.r.visibilities[&parent.def_id().unwrap().expect_local()]
|
{
|
||||||
}
|
// Trait impl item visibility is inherited from its trait when not specified
|
||||||
_ => self.resolve_visibility(&item.vis),
|
// explicitly. In that case we cannot determine it here in early resolve,
|
||||||
};
|
// so we leave a hole in the visibility table to be filled later.
|
||||||
// FIXME: For historical reasons the binding visibility is set to public,
|
|
||||||
// use actual visibility here instead, using enum variants as an example.
|
|
||||||
let vis_hack = ty::Visibility::Public;
|
|
||||||
self.r.define(parent, item.ident, ns, (res, vis_hack, item.span, expansion));
|
|
||||||
Some(vis)
|
|
||||||
}
|
|
||||||
AssocCtxt::Impl => {
|
|
||||||
// Trait impl item visibility is inherited from its trait when not specified
|
|
||||||
// explicitly. In that case we cannot determine it here in early resolve,
|
|
||||||
// so we leave a hole in the visibility table to be filled later.
|
|
||||||
// Inherent impl item visibility is never inherited from other items.
|
|
||||||
if matches!(item.vis.kind, ast::VisibilityKind::Inherited)
|
|
||||||
&& self
|
|
||||||
.r
|
|
||||||
.trait_impl_items
|
|
||||||
.contains(&ty::DefIdTree::parent(&*self.r, def_id).unwrap().expect_local())
|
|
||||||
{
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(self.resolve_visibility(&item.vis))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(vis) = vis {
|
|
||||||
self.r.visibilities.insert(local_def_id, vis);
|
self.r.visibilities.insert(local_def_id, vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctxt == AssocCtxt::Trait {
|
||||||
|
let (def_kind, ns) = match item.kind {
|
||||||
|
AssocItemKind::Const(..) => (DefKind::AssocConst, ValueNS),
|
||||||
|
AssocItemKind::Fn(box FnKind(_, ref sig, _, _)) => {
|
||||||
|
if sig.decl.has_self() {
|
||||||
|
self.r.has_self.insert(def_id);
|
||||||
|
}
|
||||||
|
(DefKind::AssocFn, ValueNS)
|
||||||
|
}
|
||||||
|
AssocItemKind::TyAlias(..) => (DefKind::AssocTy, TypeNS),
|
||||||
|
AssocItemKind::MacCall(_) => bug!(), // handled above
|
||||||
|
};
|
||||||
|
|
||||||
|
let parent = self.parent_scope.module;
|
||||||
|
let expansion = self.parent_scope.expansion;
|
||||||
|
let res = Res::Def(def_kind, def_id);
|
||||||
|
// FIXME: For historical reasons the binding visibility is set to public,
|
||||||
|
// use actual visibility here instead, using enum variants as an example.
|
||||||
|
let vis_hack = ty::Visibility::Public;
|
||||||
|
self.r.define(parent, item.ident, ns, (res, vis_hack, item.span, expansion));
|
||||||
|
}
|
||||||
|
|
||||||
visit::walk_assoc_item(self, item, ctxt);
|
visit::walk_assoc_item(self, item, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1490,19 +1475,13 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent = self.parent_scope.module;
|
let parent = self.parent_scope.module;
|
||||||
let vis = match variant.vis.kind {
|
|
||||||
// Variant visibility is inherited from its enum when not specified explicitly.
|
|
||||||
ast::VisibilityKind::Inherited => {
|
|
||||||
self.r.visibilities[&parent.def_id().unwrap().expect_local()]
|
|
||||||
}
|
|
||||||
_ => self.resolve_visibility(&variant.vis),
|
|
||||||
};
|
|
||||||
let expn_id = self.parent_scope.expansion;
|
let expn_id = self.parent_scope.expansion;
|
||||||
let ident = variant.ident;
|
let ident = variant.ident;
|
||||||
|
|
||||||
// Define a name in the type namespace.
|
// Define a name in the type namespace.
|
||||||
let def_id = self.r.local_def_id(variant.id);
|
let def_id = self.r.local_def_id(variant.id);
|
||||||
let res = Res::Def(DefKind::Variant, def_id.to_def_id());
|
let res = Res::Def(DefKind::Variant, def_id.to_def_id());
|
||||||
|
let vis = self.resolve_visibility(&variant.vis);
|
||||||
self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
|
self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
|
||||||
self.r.visibilities.insert(def_id, vis);
|
self.r.visibilities.insert(def_id, vis);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue