1use std::iter;
2
3use rustc_data_structures::fx::FxIndexMap;
4use rustc_errors::ErrorGuaranteed;
5use rustc_hir::def::DefKind;
6use rustc_hir::def_id::{DefId, LOCAL_CRATE};
7use rustc_hir::{self as hir, find_attr};
8use rustc_macros::{Decodable, Encodable, StableHash};
9use rustc_span::Span;
10use tracing::debug;
11
12use crate::query::LocalCrate;
13use crate::traits::specialization_graph;
14use crate::ty::fast_reject::{self, SimplifiedType, TreatParams};
15use crate::ty::{self, Ident, Interner, RestrictionKind, Ty, TyCtxt, VisitorResult, try_visit};
16
17#[derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for TraitDef {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
TraitDef {
def_id: ref __binding_0,
impl_restriction: ref __binding_1,
safety: ref __binding_2,
constness: ref __binding_3,
paren_sugar: ref __binding_4,
has_auto_impl: ref __binding_5,
is_marker: ref __binding_6,
is_coinductive: ref __binding_7,
is_fundamental: ref __binding_8,
skip_array_during_method_dispatch: ref __binding_9,
skip_boxed_slice_during_method_dispatch: ref __binding_10,
specialization_kind: ref __binding_11,
must_implement_one_of: ref __binding_12,
force_dyn_incompatible: ref __binding_13,
deny_explicit_impl: ref __binding_14 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
{ __binding_5.stable_hash(__hcx, __hasher); }
{ __binding_6.stable_hash(__hcx, __hasher); }
{ __binding_7.stable_hash(__hcx, __hasher); }
{ __binding_8.stable_hash(__hcx, __hasher); }
{ __binding_9.stable_hash(__hcx, __hasher); }
{ __binding_10.stable_hash(__hcx, __hasher); }
{ __binding_11.stable_hash(__hcx, __hasher); }
{ __binding_12.stable_hash(__hcx, __hasher); }
{ __binding_13.stable_hash(__hcx, __hasher); }
{ __binding_14.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for TraitDef {
fn encode(&self, __encoder: &mut __E) {
match *self {
TraitDef {
def_id: ref __binding_0,
impl_restriction: ref __binding_1,
safety: ref __binding_2,
constness: ref __binding_3,
paren_sugar: ref __binding_4,
has_auto_impl: ref __binding_5,
is_marker: ref __binding_6,
is_coinductive: ref __binding_7,
is_fundamental: ref __binding_8,
skip_array_during_method_dispatch: ref __binding_9,
skip_boxed_slice_during_method_dispatch: ref __binding_10,
specialization_kind: ref __binding_11,
must_implement_one_of: ref __binding_12,
force_dyn_incompatible: ref __binding_13,
deny_explicit_impl: ref __binding_14 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_5,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_6,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_7,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_8,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_9,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_10,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_11,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_12,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_13,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_14,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for TraitDef {
fn decode(__decoder: &mut __D) -> Self {
TraitDef {
def_id: ::rustc_serialize::Decodable::decode(__decoder),
impl_restriction: ::rustc_serialize::Decodable::decode(__decoder),
safety: ::rustc_serialize::Decodable::decode(__decoder),
constness: ::rustc_serialize::Decodable::decode(__decoder),
paren_sugar: ::rustc_serialize::Decodable::decode(__decoder),
has_auto_impl: ::rustc_serialize::Decodable::decode(__decoder),
is_marker: ::rustc_serialize::Decodable::decode(__decoder),
is_coinductive: ::rustc_serialize::Decodable::decode(__decoder),
is_fundamental: ::rustc_serialize::Decodable::decode(__decoder),
skip_array_during_method_dispatch: ::rustc_serialize::Decodable::decode(__decoder),
skip_boxed_slice_during_method_dispatch: ::rustc_serialize::Decodable::decode(__decoder),
specialization_kind: ::rustc_serialize::Decodable::decode(__decoder),
must_implement_one_of: ::rustc_serialize::Decodable::decode(__decoder),
force_dyn_incompatible: ::rustc_serialize::Decodable::decode(__decoder),
deny_explicit_impl: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
19pub struct TraitDef {
20 pub def_id: DefId,
21
22 pub impl_restriction: RestrictionKind,
24
25 pub safety: hir::Safety,
26
27 pub constness: hir::Constness,
29
30 pub paren_sugar: bool,
35
36 pub has_auto_impl: bool,
37
38 pub is_marker: bool,
42
43 pub is_coinductive: bool,
51
52 pub is_fundamental: bool,
56
57 pub skip_array_during_method_dispatch: bool,
61
62 pub skip_boxed_slice_during_method_dispatch: bool,
66
67 pub specialization_kind: TraitSpecializationKind,
70
71 pub must_implement_one_of: Option<Box<[Ident]>>,
74
75 pub force_dyn_incompatible: Option<Span>,
78
79 pub deny_explicit_impl: bool,
83}
84
85#[derive(const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
TraitSpecializationKind {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
TraitSpecializationKind::None => {}
TraitSpecializationKind::Marker => {}
TraitSpecializationKind::AlwaysApplicable => {}
}
}
}
};StableHash, #[automatically_derived]
impl ::core::cmp::PartialEq for TraitSpecializationKind {
#[inline]
fn eq(&self, other: &TraitSpecializationKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for TraitSpecializationKind {
#[inline]
fn clone(&self) -> TraitSpecializationKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TraitSpecializationKind { }Copy, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for TraitSpecializationKind {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
TraitSpecializationKind::None => { 0usize }
TraitSpecializationKind::Marker => { 1usize }
TraitSpecializationKind::AlwaysApplicable => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
TraitSpecializationKind::None => {}
TraitSpecializationKind::Marker => {}
TraitSpecializationKind::AlwaysApplicable => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for TraitSpecializationKind {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { TraitSpecializationKind::None }
1usize => { TraitSpecializationKind::Marker }
2usize => { TraitSpecializationKind::AlwaysApplicable }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `TraitSpecializationKind`, expected 0..3, actual {0}",
n));
}
}
}
}
};Decodable)]
88pub enum TraitSpecializationKind {
89 None,
91 Marker,
96 AlwaysApplicable,
101}
102
103#[derive(#[automatically_derived]
impl ::core::default::Default for TraitImpls {
#[inline]
fn default() -> TraitImpls {
TraitImpls {
blanket_impls: ::core::default::Default::default(),
non_blanket_impls: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for TraitImpls {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "TraitImpls",
"blanket_impls", &self.blanket_impls, "non_blanket_impls",
&&self.non_blanket_impls)
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for TraitImpls {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
TraitImpls {
blanket_impls: ref __binding_0,
non_blanket_impls: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
104pub struct TraitImpls {
105 blanket_impls: Vec<DefId>,
106 non_blanket_impls: FxIndexMap<SimplifiedType, Vec<DefId>>,
108}
109
110impl TraitImpls {
111 pub fn is_empty(&self) -> bool {
112 self.blanket_impls.is_empty() && self.non_blanket_impls.is_empty()
113 }
114
115 pub fn blanket_impls(&self) -> &[DefId] {
116 self.blanket_impls.as_slice()
117 }
118
119 pub fn non_blanket_impls(&self) -> &FxIndexMap<SimplifiedType, Vec<DefId>> {
120 &self.non_blanket_impls
121 }
122}
123
124impl<'tcx> TraitDef {
125 pub fn ancestors(
126 &self,
127 tcx: TyCtxt<'tcx>,
128 of_impl: DefId,
129 ) -> Result<specialization_graph::Ancestors<'tcx>, ErrorGuaranteed> {
130 specialization_graph::ancestors(tcx, self.def_id, of_impl)
131 }
132}
133
134impl<'tcx> TyCtxt<'tcx> {
135 pub fn for_each_relevant_impl<R: VisitorResult>(
139 self,
140 trait_def_id: DefId,
141 self_ty: Ty<'tcx>,
142 mut f: impl FnMut(DefId) -> R,
143 ) -> R {
144 let tcx = self;
145 let trait_impls = tcx.trait_impls_of(trait_def_id);
146 let mut consider_impls_for_simplified_type = |simp| {
147 if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
148 for &impl_def_id in impls_for_type {
149 match ::rustc_ast_ir::visit::VisitorResult::branch(f(impl_def_id)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
}try_visit!(f(impl_def_id))
150 }
151 }
152
153 R::output()
154 };
155
156 match self_ty.kind() {
157 ty::Bool
158 | ty::Char
159 | ty::Int(_)
160 | ty::Uint(_)
161 | ty::Float(_)
162 | ty::Adt(_, _)
163 | ty::Foreign(_)
164 | ty::Str
165 | ty::Array(_, _)
166 | ty::Slice(_)
167 | ty::RawPtr(_, _)
168 | ty::Ref(_, _, _)
169 | ty::FnDef(_, _)
170 | ty::FnPtr(..)
171 | ty::Dynamic(_, _)
172 | ty::Closure(..)
173 | ty::CoroutineClosure(..)
174 | ty::Coroutine(_, _)
175 | ty::Never
176 | ty::Tuple(_)
177 | ty::UnsafeBinder(_) => {
178 let simp = ty::fast_reject::simplify_type(
179 tcx,
180 self_ty,
181 ty::fast_reject::TreatParams::AsRigid,
182 )
183 .unwrap();
184 match ::rustc_ast_ir::visit::VisitorResult::branch(consider_impls_for_simplified_type(simp))
{
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};try_visit!(consider_impls_for_simplified_type(simp));
185 }
186
187 ty::Infer(ty::IntVar(_)) => {
190 use ty::IntTy::*;
191 use ty::UintTy::*;
192 let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
194 let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
195 let possible_integers = [
196 ty::SimplifiedType::Int(I8),
198 ty::SimplifiedType::Int(I16),
199 ty::SimplifiedType::Int(I32),
200 ty::SimplifiedType::Int(I64),
201 ty::SimplifiedType::Int(I128),
202 ty::SimplifiedType::Int(Isize),
203 ty::SimplifiedType::Uint(U8),
205 ty::SimplifiedType::Uint(U16),
206 ty::SimplifiedType::Uint(U32),
207 ty::SimplifiedType::Uint(U64),
208 ty::SimplifiedType::Uint(U128),
209 ty::SimplifiedType::Uint(Usize),
210 ];
211 for simp in possible_integers {
212 match ::rustc_ast_ir::visit::VisitorResult::branch(consider_impls_for_simplified_type(simp))
{
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};try_visit!(consider_impls_for_simplified_type(simp));
213 }
214 }
215
216 ty::Infer(ty::FloatVar(_)) => {
217 let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
219 let possible_floats = [
220 ty::SimplifiedType::Float(ty::FloatTy::F16),
221 ty::SimplifiedType::Float(ty::FloatTy::F32),
222 ty::SimplifiedType::Float(ty::FloatTy::F64),
223 ty::SimplifiedType::Float(ty::FloatTy::F128),
224 ];
225
226 for simp in possible_floats {
227 match ::rustc_ast_ir::visit::VisitorResult::branch(consider_impls_for_simplified_type(simp))
{
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};try_visit!(consider_impls_for_simplified_type(simp));
228 }
229 }
230
231 ty::Pat(_, _) => {
233 if let Some(simp) = ty::fast_reject::simplify_type(
234 tcx,
235 self_ty,
236 ty::fast_reject::TreatParams::AsRigid,
237 ) {
238 match ::rustc_ast_ir::visit::VisitorResult::branch(consider_impls_for_simplified_type(simp))
{
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};try_visit!(consider_impls_for_simplified_type(simp));
239 }
240 }
241
242 ty::Infer(ty::TyVar(_)) => {
244 for &impl_def_id in trait_impls.non_blanket_impls().values().flatten() {
245 match ::rustc_ast_ir::visit::VisitorResult::branch(f(impl_def_id)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};try_visit!(f(impl_def_id));
246 }
247 }
248
249 ty::Alias(ty::IsRigid::Yes, _) | ty::Placeholder(..) | ty::Error(_) => (),
254 ty::Alias(ty::IsRigid::No, _) => (),
257
258 ty::CoroutineWitness(..) => (),
262
263 ty::Param(_) | ty::Bound(_, _) => (),
265
266 ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
268 crate::util::bug::bug_fmt(format_args!("unexpected self type: {0:?}",
self_ty));bug!("unexpected self type: {self_ty:?}");
269 }
270 }
271
272 #[allow(rustc::usage_of_type_ir_traits)]
273 self.for_each_blanket_impl(trait_def_id, f)
274 }
275
276 pub fn non_blanket_impls_for_ty(
278 self,
279 trait_def_id: DefId,
280 self_ty: Ty<'tcx>,
281 ) -> impl Iterator<Item = DefId> {
282 let impls = self.trait_impls_of(trait_def_id);
283 if let Some(simp) =
284 fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
285 {
286 if let Some(impls) = impls.non_blanket_impls.get(&simp) {
287 return impls.iter().copied();
288 }
289 }
290
291 [].iter().copied()
292 }
293
294 pub fn all_impls(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> {
298 let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(trait_def_id);
299
300 blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned()
301 }
302}
303
304pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls {
306 let mut impls = TraitImpls::default();
307
308 if !trait_id.is_local() {
311 for &cnum in tcx.crates(()).iter() {
312 for &(impl_def_id, simplified_self_ty) in
313 tcx.implementations_of_trait((cnum, trait_id)).iter()
314 {
315 if let Some(simplified_self_ty) = simplified_self_ty {
316 impls
317 .non_blanket_impls
318 .entry(simplified_self_ty)
319 .or_default()
320 .push(impl_def_id);
321 } else {
322 impls.blanket_impls.push(impl_def_id);
323 }
324 }
325 }
326 }
327
328 for &impl_def_id in tcx.local_trait_impls(trait_id) {
329 let impl_def_id = impl_def_id.to_def_id();
330
331 let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity().skip_norm_wip();
332
333 if let Some(simplified_self_ty) =
334 fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::InstantiateWithInfer)
335 {
336 impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
337 } else {
338 impls.blanket_impls.push(impl_def_id);
339 }
340 }
341
342 impls
343}
344
345pub(super) fn incoherent_impls_provider(tcx: TyCtxt<'_>, simp: SimplifiedType) -> &[DefId] {
347 if let Some(def_id) = simp.def()
348 && !{
{
'done:
{
for i in ::rustc_hir::attrs::HasAttrs::get_attrs(def_id, &tcx)
{
#[allow(unused_imports)]
use ::rustc_hir::attrs::AttributeKind::*;
let i: &::rustc_hir::Attribute = i;
match i {
::rustc_hir::Attribute::Parsed(RustcHasIncoherentInherentImpls)
=> {
break 'done Some(());
}
::rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}.is_some()find_attr!(tcx, def_id, RustcHasIncoherentInherentImpls)
349 {
350 return &[];
351 }
352
353 let mut impls = Vec::new();
354 for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
355 for &impl_def_id in tcx.crate_incoherent_impls((cnum, simp)) {
356 impls.push(impl_def_id)
357 }
358 }
359 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/trait_def.rs:359",
"rustc_middle::ty::trait_def", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/trait_def.rs"),
::tracing_core::__macro_support::Option::Some(359u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::trait_def"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("impls")
}> =
::tracing::__macro_support::FieldName::new("impls");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&impls)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?impls);
360
361 tcx.arena.alloc_slice(&impls)
362}
363
364pub(super) fn traits_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
365 let mut traits = Vec::new();
366 for id in tcx.hir_free_items() {
367 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(id.owner_id) {
DefKind::Trait | DefKind::TraitAlias => true,
_ => false,
}matches!(tcx.def_kind(id.owner_id), DefKind::Trait | DefKind::TraitAlias) {
368 traits.push(id.owner_id.to_def_id())
369 }
370 }
371
372 tcx.arena.alloc_slice(&traits)
373}
374
375pub(super) fn trait_impls_in_crate_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> &[DefId] {
376 let mut trait_impls = Vec::new();
377 for id in tcx.hir_free_items() {
378 if tcx.def_kind(id.owner_id) == (DefKind::Impl { of_trait: true }) {
379 trait_impls.push(id.owner_id.to_def_id())
380 }
381 }
382
383 tcx.arena.alloc_slice(&trait_impls)
384}