Deny specializing items not in the parent impl
This commit is contained in:
parent
2e7244807a
commit
2cd5030ef5
9 changed files with 104 additions and 43 deletions
|
|
@ -1505,8 +1505,8 @@ fn assoc_ty_def(
|
|||
|
||||
if let Some(assoc_item) = trait_def
|
||||
.ancestors(tcx, impl_def_id)
|
||||
.defs(tcx, assoc_ty_name, ty::AssocKind::Type, trait_def_id)
|
||||
.next() {
|
||||
.leaf_def(tcx, assoc_ty_name, ty::AssocKind::Type) {
|
||||
|
||||
assoc_item
|
||||
} else {
|
||||
// This is saying that neither the trait nor
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ pub fn find_associated_item<'tcx>(
|
|||
let trait_def = tcx.trait_def(trait_def_id);
|
||||
|
||||
let ancestors = trait_def.ancestors(tcx, impl_data.impl_def_id);
|
||||
match ancestors.defs(tcx, item.ident, item.kind, trait_def_id).next() {
|
||||
match ancestors.leaf_def(tcx, item.ident, item.kind) {
|
||||
Some(node_item) => {
|
||||
let substs = tcx.infer_ctxt().enter(|infcx| {
|
||||
let param_env = param_env.with_reveal_all();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use crate::traits;
|
|||
use crate::ty::{self, TyCtxt, TypeFoldable};
|
||||
use crate::ty::fast_reject::{self, SimplifiedType};
|
||||
use syntax::ast::Ident;
|
||||
use crate::util::captures::Captures;
|
||||
use crate::util::nodemap::{DefIdMap, FxHashMap};
|
||||
|
||||
/// A per-trait graph of impls in specialization order. At the moment, this
|
||||
|
|
@ -419,6 +418,35 @@ impl<'tcx> Node {
|
|||
tcx.associated_items(self.def_id())
|
||||
}
|
||||
|
||||
/// Finds an associated item defined in this node.
|
||||
///
|
||||
/// If this returns `None`, the item can potentially still be found in
|
||||
/// parents of this node.
|
||||
pub fn item(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_item_name: Ident,
|
||||
trait_item_kind: ty::AssocKind,
|
||||
trait_def_id: DefId,
|
||||
) -> Option<ty::AssocItem> {
|
||||
use crate::ty::AssocKind::*;
|
||||
|
||||
tcx.associated_items(self.def_id())
|
||||
.find(move |impl_item| match (trait_item_kind, impl_item.kind) {
|
||||
| (Const, Const)
|
||||
| (Method, Method)
|
||||
| (Type, Type)
|
||||
| (Type, OpaqueTy)
|
||||
=> tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
|
||||
|
||||
| (Const, _)
|
||||
| (Method, _)
|
||||
| (Type, _)
|
||||
| (OpaqueTy, _)
|
||||
=> false,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn def_id(&self) -> DefId {
|
||||
match *self {
|
||||
Node::Impl(did) => did,
|
||||
|
|
@ -427,6 +455,7 @@ impl<'tcx> Node {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Ancestors<'tcx> {
|
||||
trait_def_id: DefId,
|
||||
specialization_graph: &'tcx Graph,
|
||||
|
|
@ -465,32 +494,18 @@ impl<T> NodeItem<T> {
|
|||
}
|
||||
|
||||
impl<'tcx> Ancestors<'tcx> {
|
||||
/// Search the items from the given ancestors, returning each definition
|
||||
/// with the given name and the given kind.
|
||||
// FIXME(#35870): avoid closures being unexported due to `impl Trait`.
|
||||
#[inline]
|
||||
pub fn defs(
|
||||
self,
|
||||
/// Finds the bottom-most (ie. most specialized) definition of an associated
|
||||
/// item.
|
||||
pub fn leaf_def(
|
||||
mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_item_name: Ident,
|
||||
trait_item_kind: ty::AssocKind,
|
||||
trait_def_id: DefId,
|
||||
) -> impl Iterator<Item = NodeItem<ty::AssocItem>> + Captures<'tcx> + 'tcx {
|
||||
self.flat_map(move |node| {
|
||||
use crate::ty::AssocKind::*;
|
||||
node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) {
|
||||
| (Const, Const)
|
||||
| (Method, Method)
|
||||
| (Type, Type)
|
||||
| (Type, OpaqueTy)
|
||||
=> tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
|
||||
|
||||
| (Const, _)
|
||||
| (Method, _)
|
||||
| (Type, _)
|
||||
| (OpaqueTy, _)
|
||||
=> false,
|
||||
}).map(move |item| NodeItem { node: node, item: item })
|
||||
) -> Option<NodeItem<ty::AssocItem>> {
|
||||
let trait_def_id = self.trait_def_id;
|
||||
self.find_map(|node| {
|
||||
node.item(tcx, trait_item_name, trait_item_kind, trait_def_id)
|
||||
.map(|item| NodeItem { node, item })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use syntax_pos::Span;
|
|||
|
||||
use crate::hir;
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::traits::specialize::specialization_graph::NodeItem;
|
||||
use crate::ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
|
||||
use crate::ty::outlives::Component;
|
||||
use crate::ty::subst::{GenericArg, Subst, SubstsRef};
|
||||
|
|
@ -667,8 +666,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn impl_item_is_final(self, node_item: &NodeItem<hir::Defaultness>) -> bool {
|
||||
node_item.item.is_final() && !self.impl_is_default(node_item.node.def_id())
|
||||
pub fn impl_item_is_final(self, assoc_item: &ty::AssocItem) -> bool {
|
||||
assoc_item.defaultness.is_final() && !self.impl_is_default(assoc_item.container.id())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue