Split AssocContainer::{InherentImpl,TraitImpl}
This commit is contained in:
parent
88a8bfcaf0
commit
9615ec7d10
33 changed files with 173 additions and 229 deletions
|
|
@ -1009,7 +1009,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
|
|||
res = res.and(check_associated_item(tcx, def_id));
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
ty::AssocContainer::Impl => {}
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
|
||||
ty::AssocContainer::Trait => {
|
||||
res = res.and(check_trait_item(tcx, def_id));
|
||||
}
|
||||
|
|
@ -1026,7 +1026,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
|
|||
res = res.and(check_associated_item(tcx, def_id));
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
ty::AssocContainer::Impl => {}
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
|
||||
ty::AssocContainer::Trait => {
|
||||
res = res.and(check_trait_item(tcx, def_id));
|
||||
}
|
||||
|
|
@ -1043,7 +1043,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
|
|||
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
let has_type = match assoc_item.container {
|
||||
ty::AssocContainer::Impl => true,
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
|
||||
ty::AssocContainer::Trait => {
|
||||
tcx.ensure_ok().explicit_item_bounds(def_id);
|
||||
tcx.ensure_ok().explicit_item_self_bounds(def_id);
|
||||
|
|
@ -1177,12 +1177,9 @@ fn check_impl_items_against_trait<'tcx>(
|
|||
|
||||
for &impl_item in impl_item_refs {
|
||||
let ty_impl_item = tcx.associated_item(impl_item);
|
||||
let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
|
||||
tcx.associated_item(trait_item_id)
|
||||
} else {
|
||||
// Checked in `associated_item`.
|
||||
tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
|
||||
continue;
|
||||
let ty_trait_item = match ty_impl_item.expect_trait_impl() {
|
||||
Ok(trait_item_id) => tcx.associated_item(trait_item_id),
|
||||
Err(ErrorGuaranteed { .. }) => continue,
|
||||
};
|
||||
|
||||
let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub(super) fn compare_impl_item(
|
|||
impl_item_def_id: LocalDefId,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let impl_item = tcx.associated_item(impl_item_def_id);
|
||||
let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap());
|
||||
let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?);
|
||||
let impl_trait_ref =
|
||||
tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity();
|
||||
debug!(?impl_trait_ref);
|
||||
|
|
@ -446,7 +446,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
impl_m_def_id: LocalDefId,
|
||||
) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
|
||||
let impl_m = tcx.associated_item(impl_m_def_id.to_def_id());
|
||||
let trait_m = tcx.associated_item(impl_m.trait_item_def_id.unwrap());
|
||||
let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?);
|
||||
let impl_trait_ref =
|
||||
tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity();
|
||||
// First, check a few of the same things as `compare_impl_method`,
|
||||
|
|
@ -1449,7 +1449,9 @@ fn compare_self_type<'tcx>(
|
|||
|
||||
let self_string = |method: ty::AssocItem| {
|
||||
let untransformed_self_ty = match method.container {
|
||||
ty::AssocContainer::Impl => impl_trait_ref.self_ty(),
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
impl_trait_ref.self_ty()
|
||||
}
|
||||
ty::AssocContainer::Trait => tcx.types.self_param,
|
||||
};
|
||||
let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
|
||||
|
|
@ -2458,8 +2460,12 @@ fn param_env_with_gat_bounds<'tcx>(
|
|||
|
||||
for impl_ty in impl_tys_to_install {
|
||||
let trait_ty = match impl_ty.container {
|
||||
ty::AssocContainer::InherentImpl => bug!(),
|
||||
ty::AssocContainer::Trait => impl_ty,
|
||||
ty::AssocContainer::Impl => tcx.associated_item(impl_ty.trait_item_def_id.unwrap()),
|
||||
ty::AssocContainer::TraitImpl(Err(_)) => continue,
|
||||
ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) => {
|
||||
tcx.associated_item(trait_item_def_id)
|
||||
}
|
||||
};
|
||||
|
||||
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
|
||||
|
|
|
|||
|
|
@ -944,12 +944,13 @@ pub(crate) fn check_associated_item(
|
|||
|
||||
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
|
||||
// other `Foo` impls are incoherent.
|
||||
tcx.ensure_ok()
|
||||
.coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
|
||||
tcx.ensure_ok().coherent_trait(tcx.parent(item.trait_item_or_self()?))?;
|
||||
|
||||
let self_ty = match item.container {
|
||||
ty::AssocContainer::Trait => tcx.types.self_param,
|
||||
ty::AssocContainer::Impl => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
tcx.type_of(item.container_id(tcx)).instantiate_identity()
|
||||
}
|
||||
};
|
||||
|
||||
let span = tcx.def_span(item_id);
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.set_tainted_by_errors(e);
|
||||
}
|
||||
}
|
||||
ty::AssocContainer::Impl => {
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
if segments.len() == 1 {
|
||||
// `<T>::assoc` will end up here, and so
|
||||
// can `T::assoc`. If this came from an
|
||||
|
|
|
|||
|
|
@ -2354,7 +2354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// We want it to always point to the trait item.
|
||||
// If we're pointing at an inherent function, we don't need to do anything,
|
||||
// so we fetch the parent and verify if it's a trait item.
|
||||
&& let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
|
||||
&& let Ok(maybe_trait_item_def_id) = assoc_item.trait_item_or_self()
|
||||
&& let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
|
||||
// Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
|
||||
&& let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id)
|
||||
|
|
|
|||
|
|
@ -278,8 +278,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
|
|||
{
|
||||
if let Some(item) = tcx.opt_associated_item(def_id.into())
|
||||
&& let ty::AssocKind::Const { .. } = item.kind
|
||||
&& let ty::AssocContainer::Impl = item.container
|
||||
&& let Some(trait_item_def_id) = item.trait_item_def_id
|
||||
&& let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container
|
||||
{
|
||||
let impl_def_id = item.container_id(tcx);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
|
||||
|
|
|
|||
|
|
@ -1659,7 +1659,7 @@ impl<'tcx> Pick<'tcx> {
|
|||
/// Do not use for type checking.
|
||||
pub(crate) fn differs_from(&self, other: &Self) -> bool {
|
||||
let Self {
|
||||
item: AssocItem { def_id, kind: _, container: _, trait_item_def_id: _ },
|
||||
item: AssocItem { def_id, kind: _, container: _ },
|
||||
kind: _,
|
||||
import_ids: _,
|
||||
autoderefs: _,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ use rustc_middle::bug;
|
|||
use rustc_middle::lint::LevelAndSource;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
|
||||
use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
|
||||
use rustc_session::lint::FutureIncompatibilityReason;
|
||||
// hardwired lints from rustc_lint_defs
|
||||
pub use rustc_session::lint::builtin::*;
|
||||
|
|
@ -61,7 +61,6 @@ use crate::lints::{
|
|||
BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
|
||||
BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel,
|
||||
};
|
||||
use crate::nonstandard_style::{MethodLateContext, method_context};
|
||||
use crate::{
|
||||
EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
|
||||
fluent_generated as fluent,
|
||||
|
|
@ -469,14 +468,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
}
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
let context = method_context(cx, impl_item.owner_id.def_id);
|
||||
let container = cx.tcx.associated_item(impl_item.owner_id.def_id).container;
|
||||
|
||||
match context {
|
||||
match container {
|
||||
// If the method is an impl for a trait, don't doc.
|
||||
MethodLateContext::TraitImpl => return,
|
||||
MethodLateContext::TraitAutoImpl => {}
|
||||
AssocContainer::TraitImpl(_) => return,
|
||||
AssocContainer::Trait => {}
|
||||
// If the method is an impl for an item with docs_hidden, don't doc.
|
||||
MethodLateContext::PlainImpl => {
|
||||
AssocContainer::InherentImpl => {
|
||||
let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id());
|
||||
let impl_ty = cx.tcx.type_of(parent).instantiate_identity();
|
||||
let outerdef = match impl_ty.kind() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::intravisit::{FnKind, Visitor};
|
||||
use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind, find_attr};
|
||||
use rustc_middle::hir::nested_filter::All;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::AssocContainer;
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::{declare_lint, declare_lint_pass};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
|
@ -20,24 +20,6 @@ use crate::lints::{
|
|||
};
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub(crate) enum MethodLateContext {
|
||||
TraitAutoImpl,
|
||||
TraitImpl,
|
||||
PlainImpl,
|
||||
}
|
||||
|
||||
pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext {
|
||||
let item = cx.tcx.associated_item(id);
|
||||
match item.container {
|
||||
ty::AssocContainer::Trait => MethodLateContext::TraitAutoImpl,
|
||||
ty::AssocContainer::Impl => match cx.tcx.impl_trait_ref(item.container_id(cx.tcx)) {
|
||||
Some(_) => MethodLateContext::TraitImpl,
|
||||
None => MethodLateContext::PlainImpl,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `non_camel_case_types` lint detects types, variants, traits and
|
||||
/// type parameters that don't have camel case names.
|
||||
|
|
@ -384,8 +366,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
|
|||
id: LocalDefId,
|
||||
) {
|
||||
match &fk {
|
||||
FnKind::Method(ident, sig, ..) => match method_context(cx, id) {
|
||||
MethodLateContext::PlainImpl => {
|
||||
FnKind::Method(ident, sig, ..) => match cx.tcx.associated_item(id).container {
|
||||
AssocContainer::InherentImpl => {
|
||||
if sig.header.abi != ExternAbi::Rust
|
||||
&& find_attr!(cx.tcx.get_all_attrs(id), AttributeKind::NoMangle(..))
|
||||
{
|
||||
|
|
@ -393,10 +375,10 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
|
|||
}
|
||||
self.check_snake_case(cx, "method", ident);
|
||||
}
|
||||
MethodLateContext::TraitAutoImpl => {
|
||||
AssocContainer::Trait => {
|
||||
self.check_snake_case(cx, "trait method", ident);
|
||||
}
|
||||
_ => (),
|
||||
AssocContainer::TraitImpl(_) => {}
|
||||
},
|
||||
FnKind::ItemFn(ident, _, header) => {
|
||||
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
|
||||
|
|
|
|||
|
|
@ -1194,10 +1194,6 @@ impl<'a> CrateMetadataRef<'a> {
|
|||
self.root.tables.default_fields.get(self, id).map(|d| d.decode(self))
|
||||
}
|
||||
|
||||
fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> {
|
||||
self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self))
|
||||
}
|
||||
|
||||
fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId {
|
||||
self.root
|
||||
.tables
|
||||
|
|
@ -1359,14 +1355,9 @@ impl<'a> CrateMetadataRef<'a> {
|
|||
}
|
||||
_ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
|
||||
};
|
||||
let container = self.root.tables.assoc_container.get(self, id).unwrap();
|
||||
let container = self.root.tables.assoc_container.get(self, id).unwrap().decode(self);
|
||||
|
||||
ty::AssocItem {
|
||||
kind,
|
||||
def_id: self.local_def_id(id),
|
||||
trait_item_def_id: self.get_trait_item_def_id(id),
|
||||
container,
|
||||
}
|
||||
ty::AssocItem { kind, def_id: self.local_def_id(id), container }
|
||||
}
|
||||
|
||||
fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> {
|
||||
|
|
|
|||
|
|
@ -1254,7 +1254,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
|||
DefKind::AssocTy => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
ty::AssocContainer::Impl => true,
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
|
||||
ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(),
|
||||
}
|
||||
}
|
||||
|
|
@ -1726,23 +1726,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
let item = tcx.associated_item(def_id);
|
||||
|
||||
self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
|
||||
self.tables.assoc_container.set_some(def_id.index, item.container);
|
||||
record!(self.tables.assoc_container[def_id] <- item.container);
|
||||
|
||||
match item.container {
|
||||
AssocContainer::Trait => {
|
||||
if item.is_type() {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
self.encode_explicit_item_self_bounds(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
}
|
||||
AssocContainer::Impl => {
|
||||
if let Some(trait_item_def_id) = item.trait_item_def_id {
|
||||
self.tables.trait_item_def_id.set_some(def_id.index, trait_item_def_id.into());
|
||||
}
|
||||
if let AssocContainer::Trait = item.container
|
||||
&& item.is_type()
|
||||
{
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
self.encode_explicit_item_self_bounds(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind {
|
||||
|
|
|
|||
|
|
@ -447,7 +447,6 @@ define_tables! {
|
|||
coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>,
|
||||
eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
|
||||
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
|
||||
trait_item_def_id: Table<DefIndex, RawDefId>,
|
||||
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
|
||||
default_fields: Table<DefIndex, LazyValue<DefId>>,
|
||||
params_in_repr: Table<DefIndex, LazyValue<DenseBitSet<u32>>>,
|
||||
|
|
@ -459,7 +458,7 @@ define_tables! {
|
|||
def_keys: Table<DefIndex, LazyValue<DefKey>>,
|
||||
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
|
||||
variant_data: Table<DefIndex, LazyValue<VariantData>>,
|
||||
assoc_container: Table<DefIndex, ty::AssocContainer>,
|
||||
assoc_container: Table<DefIndex, LazyValue<ty::AssocContainer>>,
|
||||
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
|
||||
proc_macro: Table<DefIndex, MacroKind>,
|
||||
deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
|
||||
|
|
|
|||
|
|
@ -221,13 +221,6 @@ fixed_size_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
fixed_size_enum! {
|
||||
ty::AssocContainer {
|
||||
( Trait )
|
||||
( Impl )
|
||||
}
|
||||
}
|
||||
|
||||
fixed_size_enum! {
|
||||
MacroKind {
|
||||
( Attr )
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_hir::def::{DefKind, Namespace};
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_macros::{Decodable, Encodable, HashStable};
|
||||
use rustc_span::{Ident, Symbol};
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Symbol};
|
||||
|
||||
use super::{TyCtxt, Visibility};
|
||||
use crate::ty;
|
||||
|
|
@ -13,7 +13,9 @@ use crate::ty;
|
|||
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
|
||||
pub enum AssocContainer {
|
||||
Trait,
|
||||
Impl,
|
||||
InherentImpl,
|
||||
/// The `DefId` points to the trait item being implemented.
|
||||
TraitImpl(Result<DefId, ErrorGuaranteed>),
|
||||
}
|
||||
|
||||
/// Information about an associated item
|
||||
|
|
@ -22,10 +24,6 @@ pub struct AssocItem {
|
|||
pub def_id: DefId,
|
||||
pub kind: AssocKind,
|
||||
pub container: AssocContainer,
|
||||
|
||||
/// If this is an item in an impl of a trait then this is the `DefId` of
|
||||
/// the associated item on the trait that this implements.
|
||||
pub trait_item_def_id: Option<DefId>,
|
||||
}
|
||||
|
||||
impl AssocItem {
|
||||
|
|
@ -58,6 +56,30 @@ impl AssocItem {
|
|||
tcx.defaultness(self.def_id)
|
||||
}
|
||||
|
||||
pub fn expect_trait_impl(&self) -> Result<DefId, ErrorGuaranteed> {
|
||||
let AssocContainer::TraitImpl(trait_item_id) = self.container else {
|
||||
bug!("expected item to be in a trait impl: {:?}", self.def_id);
|
||||
};
|
||||
trait_item_id
|
||||
}
|
||||
|
||||
/// If this is a trait impl item, returns the `DefId` of the trait item this implements.
|
||||
/// Otherwise, returns `DefId` for self. Returns an Err in case the trait item was not
|
||||
/// resolved successfully.
|
||||
pub fn trait_item_or_self(&self) -> Result<DefId, ErrorGuaranteed> {
|
||||
match self.container {
|
||||
AssocContainer::TraitImpl(id) => id,
|
||||
AssocContainer::Trait | AssocContainer::InherentImpl => Ok(self.def_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trait_item_def_id(&self) -> Option<DefId> {
|
||||
match self.container {
|
||||
AssocContainer::TraitImpl(Ok(id)) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility<DefId> {
|
||||
tcx.visibility(self.def_id)
|
||||
|
|
@ -71,7 +93,7 @@ impl AssocItem {
|
|||
#[inline]
|
||||
pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
||||
match self.container {
|
||||
AssocContainer::Impl => None,
|
||||
AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => None,
|
||||
AssocContainer::Trait => Some(tcx.parent(self.def_id)),
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +101,9 @@ impl AssocItem {
|
|||
#[inline]
|
||||
pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
|
||||
match self.container {
|
||||
AssocContainer::Impl => Some(tcx.parent(self.def_id)),
|
||||
AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => {
|
||||
Some(tcx.parent(self.def_id))
|
||||
}
|
||||
AssocContainer::Trait => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -156,11 +180,11 @@ impl AssocItem {
|
|||
return false;
|
||||
}
|
||||
|
||||
let def_id = match (self.container, self.trait_item_def_id) {
|
||||
(AssocContainer::Trait, _) => self.def_id,
|
||||
(AssocContainer::Impl, Some(trait_item_did)) => trait_item_did,
|
||||
// Inherent impl but this attr is only applied to trait assoc items.
|
||||
(AssocContainer::Impl, None) => return true,
|
||||
let def_id = match self.container {
|
||||
AssocContainer::Trait => self.def_id,
|
||||
AssocContainer::TraitImpl(Ok(trait_item_did)) => trait_item_did,
|
||||
AssocContainer::TraitImpl(Err(_)) => return false,
|
||||
AssocContainer::InherentImpl => return true,
|
||||
};
|
||||
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
|||
use crate::ty::normalize_erasing_regions::NormalizationError;
|
||||
use crate::ty::print::{FmtPrinter, Print};
|
||||
use crate::ty::{
|
||||
self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
self, AssocContainer, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
|
||||
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
|
||||
/// An `InstanceKind` along with the args that are needed to substitute the instance.
|
||||
|
|
@ -611,26 +611,23 @@ impl<'tcx> Instance<'tcx> {
|
|||
debug!(" => fn pointer created for virtual call");
|
||||
resolved.def = InstanceKind::ReifyShim(def_id, reason);
|
||||
}
|
||||
// Reify `Trait::method` implementations if KCFI is enabled
|
||||
// FIXME(maurer) only reify it if it is a vtable-safe function
|
||||
_ if tcx.sess.is_sanitizer_kcfi_enabled()
|
||||
&& tcx
|
||||
.opt_associated_item(def_id)
|
||||
.and_then(|assoc| assoc.trait_item_def_id)
|
||||
.is_some() =>
|
||||
{
|
||||
// If this function could also go in a vtable, we need to `ReifyShim` it with
|
||||
// KCFI because it can only attach one type per function.
|
||||
resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
|
||||
}
|
||||
// Reify `::call`-like method implementations if KCFI is enabled
|
||||
_ if tcx.sess.is_sanitizer_kcfi_enabled()
|
||||
&& tcx.is_closure_like(resolved.def_id()) =>
|
||||
{
|
||||
// Reroute through a reify via the *unresolved* instance. The resolved one can't
|
||||
// be directly reified because it's closure-like. The reify can handle the
|
||||
// unresolved instance.
|
||||
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
|
||||
_ if tcx.sess.is_sanitizer_kcfi_enabled() => {
|
||||
// Reify `::call`-like method implementations
|
||||
if tcx.is_closure_like(resolved.def_id()) {
|
||||
// Reroute through a reify via the *unresolved* instance. The resolved one can't
|
||||
// be directly reified because it's closure-like. The reify can handle the
|
||||
// unresolved instance.
|
||||
resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
|
||||
// Reify `Trait::method` implementations
|
||||
// FIXME(maurer) only reify it if it is a vtable-safe function
|
||||
} else if let Some(assoc) = tcx.opt_associated_item(def_id)
|
||||
&& let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
|
||||
assoc.container
|
||||
{
|
||||
// If this function could also go in a vtable, we need to `ReifyShim` it with
|
||||
// KCFI because it can only attach one type per function.
|
||||
resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1936,11 +1936,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
/// Returns the trait item that is implemented by the given item `DefId`.
|
||||
pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> {
|
||||
let assoc = self.opt_associated_item(def_id.into_query_param())?;
|
||||
if assoc.container != AssocContainer::Impl {
|
||||
return None;
|
||||
}
|
||||
assoc.trait_item_def_id
|
||||
self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id()
|
||||
}
|
||||
|
||||
/// If the given `DefId` is an associated item of a trait,
|
||||
|
|
@ -2158,17 +2154,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
let Some(item) = self.opt_associated_item(def_id) else {
|
||||
return false;
|
||||
};
|
||||
if item.container != ty::AssocContainer::Impl {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(trait_item_def_id) = item.trait_item_def_id else {
|
||||
let AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container else {
|
||||
return false;
|
||||
};
|
||||
|
||||
return !self
|
||||
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
||||
.is_empty();
|
||||
!self.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id).is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
|
|||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::middle::stability::{AllowUnstable, Deprecated, DeprecationEntry, EvalResult};
|
||||
use rustc_middle::query::{LocalCrate, Providers};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{AssocContainer, TyCtxt};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::lint::builtin::{DEPRECATED, INEFFECTIVE_UNSTABLE_TRAIT_IMPL};
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
|
|
@ -710,7 +710,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
|||
for impl_item_ref in items {
|
||||
let impl_item = self.tcx.associated_item(impl_item_ref.owner_id);
|
||||
|
||||
if let Some(def_id) = impl_item.trait_item_def_id {
|
||||
if let AssocContainer::TraitImpl(Ok(def_id)) = impl_item.container {
|
||||
// Pass `None` to skip deprecation warnings.
|
||||
self.tcx.check_stability(
|
||||
def_id,
|
||||
|
|
|
|||
|
|
@ -1613,10 +1613,6 @@ pub struct AssocItem {
|
|||
pub def_id: AssocDef,
|
||||
pub kind: AssocKind,
|
||||
pub container: AssocContainer,
|
||||
|
||||
/// If this is an item in an impl of a trait then this is the `DefId` of
|
||||
/// the associated item on the trait that this implements.
|
||||
pub trait_item_def_id: Option<AssocDef>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
|
||||
|
|
@ -1637,8 +1633,10 @@ pub enum AssocKind {
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum AssocContainer {
|
||||
InherentImpl,
|
||||
/// The `AssocDef` points to the trait item being implemented.
|
||||
TraitImpl(AssocDef),
|
||||
Trait,
|
||||
Impl,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
|
|
|
|||
|
|
@ -1079,11 +1079,18 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
|
|||
impl<'tcx> Stable<'tcx> for ty::AssocContainer {
|
||||
type T = crate::ty::AssocContainer;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
|
||||
fn stable(
|
||||
&self,
|
||||
tables: &mut Tables<'_, BridgeTys>,
|
||||
_: &CompilerCtxt<'_, BridgeTys>,
|
||||
) -> Self::T {
|
||||
use crate::ty::AssocContainer;
|
||||
match self {
|
||||
ty::AssocContainer::Trait => AssocContainer::Trait,
|
||||
ty::AssocContainer::Impl => AssocContainer::Impl,
|
||||
ty::AssocContainer::InherentImpl => AssocContainer::InherentImpl,
|
||||
ty::AssocContainer::TraitImpl(trait_item_id) => {
|
||||
AssocContainer::TraitImpl(tables.assoc_def(trait_item_id.unwrap()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1100,7 +1107,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
|
|||
def_id: tables.assoc_def(self.def_id),
|
||||
kind: self.kind.stable(tables, cx),
|
||||
container: self.container.stable(tables, cx),
|
||||
trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ fn foo(&self) -> Self::T { String::new() }
|
|||
"associated type defaults can't be assumed inside the \
|
||||
trait defining them"
|
||||
}
|
||||
ty::AssocContainer::Impl => {
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
"associated type is `default` and may be overridden"
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -571,13 +571,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
// but right now it's not really very smart when it comes to implicit `Sized`
|
||||
// predicates and bounds on the trait itself.
|
||||
|
||||
let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
|
||||
let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else {
|
||||
return;
|
||||
};
|
||||
let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
|
||||
let trait_args = trait_ref
|
||||
.instantiate_identity()
|
||||
// Replace the explicit self type with `Self` for better suggestion rendering
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ pub fn call_kind<'tcx>(
|
|||
let parent = tcx.opt_associated_item(method_did).and_then(|assoc| {
|
||||
let container_id = assoc.container_id(tcx);
|
||||
match assoc.container {
|
||||
AssocContainer::Impl => tcx.trait_id_of_impl(container_id),
|
||||
AssocContainer::InherentImpl => None,
|
||||
AssocContainer::TraitImpl(_) => tcx.trait_id_of_impl(container_id),
|
||||
AssocContainer::Trait => Some(container_id),
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ pub(crate) fn assoc_def(
|
|||
if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
|
||||
// Ensure that the impl is constrained, otherwise projection may give us
|
||||
// bad unconstrained infer vars.
|
||||
if assoc_item.item.container == ty::AssocContainer::Impl
|
||||
if let ty::AssocContainer::TraitImpl(_) = assoc_item.item.container
|
||||
&& let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
|
||||
{
|
||||
tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems {
|
|||
fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId> {
|
||||
tcx.associated_items(impl_id)
|
||||
.in_definition_order()
|
||||
.filter_map(|item| item.trait_item_def_id.map(|trait_item| (trait_item, item.def_id)))
|
||||
.filter_map(|item| item.trait_item_def_id().map(|trait_item| (trait_item, item.def_id)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
@ -97,12 +97,7 @@ fn associated_item_from_trait_item(
|
|||
}
|
||||
};
|
||||
|
||||
ty::AssocItem {
|
||||
kind,
|
||||
def_id: owner_id.to_def_id(),
|
||||
trait_item_def_id: Some(owner_id.to_def_id()),
|
||||
container: ty::AssocContainer::Trait,
|
||||
}
|
||||
ty::AssocItem { kind, def_id: owner_id.to_def_id(), container: ty::AssocContainer::Trait }
|
||||
}
|
||||
|
||||
fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> ty::AssocItem {
|
||||
|
|
@ -118,15 +113,13 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>
|
|||
}
|
||||
};
|
||||
|
||||
ty::AssocItem {
|
||||
kind,
|
||||
def_id: owner_id.to_def_id(),
|
||||
container: ty::AssocContainer::Impl,
|
||||
trait_item_def_id: match impl_item.impl_kind {
|
||||
ImplItemImplKind::Inherent { .. } => None,
|
||||
ImplItemImplKind::Trait { trait_item_def_id, .. } => trait_item_def_id.ok(),
|
||||
},
|
||||
}
|
||||
let container = match impl_item.impl_kind {
|
||||
ImplItemImplKind::Inherent { .. } => ty::AssocContainer::InherentImpl,
|
||||
ImplItemImplKind::Trait { trait_item_def_id, .. } => {
|
||||
ty::AssocContainer::TraitImpl(trait_item_def_id)
|
||||
}
|
||||
};
|
||||
ty::AssocItem { kind, def_id: owner_id.to_def_id(), container }
|
||||
}
|
||||
struct RPITVisitor<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
@ -262,7 +255,6 @@ fn associated_type_for_impl_trait_in_trait(
|
|||
}),
|
||||
},
|
||||
def_id,
|
||||
trait_item_def_id: None,
|
||||
container: ty::AssocContainer::Trait,
|
||||
});
|
||||
|
||||
|
|
@ -328,8 +320,7 @@ fn associated_type_for_impl_trait_in_impl(
|
|||
}),
|
||||
},
|
||||
def_id,
|
||||
trait_item_def_id: Some(trait_assoc_def_id),
|
||||
container: ty::AssocContainer::Impl,
|
||||
container: ty::AssocContainer::TraitImpl(Ok(trait_assoc_def_id)),
|
||||
});
|
||||
|
||||
// Copy visility of the containing function.
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
|||
|
||||
for &assoc in self.tcx.associated_items(parent).in_definition_order() {
|
||||
trace!(?assoc);
|
||||
if assoc.trait_item_def_id != Some(alias_ty.def_id) {
|
||||
if assoc.expect_trait_impl() != Ok(alias_ty.def_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1295,11 +1295,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
|||
simplify::move_bounds_to_generic_parameters(&mut generics);
|
||||
|
||||
match assoc_item.container {
|
||||
ty::AssocContainer::Impl => ImplAssocConstItem(Box::new(Constant {
|
||||
generics,
|
||||
kind: ConstantKind::Extern { def_id: assoc_item.def_id },
|
||||
type_: ty,
|
||||
})),
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
ImplAssocConstItem(Box::new(Constant {
|
||||
generics,
|
||||
kind: ConstantKind::Extern { def_id: assoc_item.def_id },
|
||||
type_: ty,
|
||||
}))
|
||||
}
|
||||
ty::AssocContainer::Trait => {
|
||||
if tcx.defaultness(assoc_item.def_id).has_value() {
|
||||
ProvidedAssocConstItem(Box::new(Constant {
|
||||
|
|
@ -1318,7 +1320,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
|||
|
||||
if has_self {
|
||||
let self_ty = match assoc_item.container {
|
||||
ty::AssocContainer::Impl => {
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
|
||||
tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity()
|
||||
}
|
||||
ty::AssocContainer::Trait => tcx.types.self_param,
|
||||
|
|
@ -1338,13 +1340,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
|||
}
|
||||
|
||||
let provided = match assoc_item.container {
|
||||
ty::AssocContainer::Impl => true,
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
|
||||
ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(),
|
||||
};
|
||||
if provided {
|
||||
let defaultness = match assoc_item.container {
|
||||
ty::AssocContainer::Impl => Some(assoc_item.defaultness(tcx)),
|
||||
ty::AssocContainer::Trait => None,
|
||||
ty::AssocContainer::TraitImpl(_) => Some(assoc_item.defaultness(tcx)),
|
||||
ty::AssocContainer::InherentImpl | ty::AssocContainer::Trait => None,
|
||||
};
|
||||
MethodItem(item, defaultness)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -690,16 +690,13 @@ impl Item {
|
|||
// rustc's `is_const_fn` returns `true` for associated functions that have an `impl const` parent
|
||||
// or that have a `const trait` parent. Do not display those as `const` in rustdoc because we
|
||||
// won't be printing correct syntax plus the syntax is unstable.
|
||||
match tcx.opt_associated_item(def_id) {
|
||||
Some(ty::AssocItem {
|
||||
container: ty::AssocContainer::Impl,
|
||||
trait_item_def_id: Some(_),
|
||||
..
|
||||
})
|
||||
| Some(ty::AssocItem { container: ty::AssocContainer::Trait, .. }) => {
|
||||
hir::Constness::NotConst
|
||||
}
|
||||
None | Some(_) => hir::Constness::Const,
|
||||
if let Some(assoc) = tcx.opt_associated_item(def_id)
|
||||
&& let ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) =
|
||||
assoc.container
|
||||
{
|
||||
hir::Constness::NotConst
|
||||
} else {
|
||||
hir::Constness::Const
|
||||
}
|
||||
} else {
|
||||
hir::Constness::NotConst
|
||||
|
|
@ -779,17 +776,13 @@ impl Item {
|
|||
| RequiredAssocTypeItem(..)
|
||||
| RequiredMethodItem(..)
|
||||
| MethodItem(..) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
let is_trait_item = match assoc_item.container {
|
||||
ty::AssocContainer::Trait => true,
|
||||
ty::AssocContainer::Impl => {
|
||||
// Trait impl items always inherit the impl's visibility --
|
||||
// we don't want to show `pub`.
|
||||
tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some()
|
||||
match tcx.associated_item(def_id).container {
|
||||
// Trait impl items always inherit the impl's visibility --
|
||||
// we don't want to show `pub`.
|
||||
ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
if is_trait_item {
|
||||
return None;
|
||||
ty::AssocContainer::InherentImpl => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use rustc_hir::Attribute;
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::Visibility;
|
||||
use rustc_middle::ty::{AssocContainer, Visibility};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::symbol::kw;
|
||||
|
|
@ -246,12 +246,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
|||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
||||
// If the method is an impl for a trait, don't doc.
|
||||
if let Some(cid) = cx.tcx.associated_item(impl_item.owner_id).impl_container(cx.tcx) {
|
||||
if cx.tcx.impl_trait_ref(cid).is_some() {
|
||||
match cx.tcx.associated_item(impl_item.owner_id).container {
|
||||
AssocContainer::Trait | AssocContainer::TraitImpl(_) => {
|
||||
note_prev_span_then_ret!(self.prev_span, impl_item.span);
|
||||
}
|
||||
} else {
|
||||
note_prev_span_then_ret!(self.prev_span, impl_item.span);
|
||||
},
|
||||
AssocContainer::InherentImpl => {}
|
||||
}
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
|
||||
|
|
|
|||
|
|
@ -167,7 +167,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
|||
let container_id = assoc_item.container_id(cx.tcx);
|
||||
let trait_def_id = match assoc_item.container {
|
||||
AssocContainer::Trait => Some(container_id),
|
||||
AssocContainer::Impl => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
|
||||
AssocContainer::TraitImpl(_) => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
|
||||
AssocContainer::InherentImpl => None,
|
||||
};
|
||||
|
||||
if let Some(trait_def_id) = trait_def_id
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
|
|||
.tcx
|
||||
.associated_items(item.owner_id)
|
||||
.in_definition_order()
|
||||
.filter_map(|assoc_item| assoc_item.trait_item_def_id)
|
||||
.filter_map(|assoc_item| assoc_item.expect_trait_impl().ok())
|
||||
.collect();
|
||||
|
||||
for assoc in cx
|
||||
|
|
|
|||
|
|
@ -3251,7 +3251,7 @@ pub fn get_path_from_caller_to_method_type<'tcx>(
|
|||
let def_id = assoc_item.container_id(tcx);
|
||||
match assoc_item.container {
|
||||
rustc_ty::AssocContainer::Trait => get_path_to_callee(tcx, from, def_id),
|
||||
rustc_ty::AssocContainer::Impl => {
|
||||
rustc_ty::AssocContainer::InherentImpl | rustc_ty::AssocContainer::TraitImpl(_) => {
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
get_path_to_ty(tcx, from, ty, args)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ where
|
|||
{
|
||||
fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||
//~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add`
|
||||
//~| ERROR type annotations needed
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add`
|
|||
|
|
||||
LL | / fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | loop {}
|
||||
LL | | }
|
||||
| |_____^ not a member of trait `std::ops::Add`
|
||||
|
|
@ -39,21 +38,7 @@ LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
|
|||
= note: expressions using a const parameter must map each value to a distinct output value
|
||||
= note: proving the result of expressions other than the parameter are unique is not supported
|
||||
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/post-analysis-user-facing-param-env.rs:12:40
|
||||
|
|
||||
LL | fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||
| ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM`
|
||||
|
|
||||
note: required for `Foo` to implement `Add<&'a Foo>`
|
||||
--> $DIR/post-analysis-user-facing-param-env.rs:6:28
|
||||
|
|
||||
LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
|
||||
| ---------------- ^^^^^^^^^^^^^^^^^^^^^^ ^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0046, E0207, E0284, E0407.
|
||||
Some errors have detailed explanations: E0046, E0207, E0407.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue