1use rustc_errors::ErrorGuaranteed;
2use rustc_hir::def_id::DefId;
3use rustc_macros::extension;
4use rustc_middle::bug;
5pub use rustc_middle::traits::specialization_graph::*;
6use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
7use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
8use tracing::{debug, instrument};
9
10use super::OverlapError;
11use crate::traits;
12
13#[derive(#[automatically_derived]
impl ::core::marker::Copy for FutureCompatOverlapErrorKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for FutureCompatOverlapErrorKind {
#[inline]
fn clone(&self) -> FutureCompatOverlapErrorKind { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for FutureCompatOverlapErrorKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "LeakCheck")
}
}Debug)]
14pub enum FutureCompatOverlapErrorKind {
15 LeakCheck,
16}
17
18#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for FutureCompatOverlapError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"FutureCompatOverlapError", "error", &self.error, "kind",
&&self.kind)
}
}Debug)]
19pub struct FutureCompatOverlapError<'tcx> {
20 pub error: OverlapError<'tcx>,
21 pub kind: FutureCompatOverlapErrorKind,
22}
23
24#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for Inserted<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Inserted::BecameNewSibling(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"BecameNewSibling", &__self_0),
Inserted::ReplaceChildren(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ReplaceChildren", &__self_0),
Inserted::ShouldRecurseOn(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ShouldRecurseOn", &__self_0),
}
}
}Debug)]
26enum Inserted<'tcx> {
27 BecameNewSibling(Option<FutureCompatOverlapError<'tcx>>),
29
30 ReplaceChildren(Vec<DefId>),
32
33 ShouldRecurseOn(DefId),
35}
36
37impl<'tcx> ChildrenExt<'tcx> for Children {
#[doc =
" Insert an impl into this set of children without comparing to any existing impls."]
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
if let Some(st) =
fast_reject::simplify_type(tcx, trait_ref.self_ty(),
TreatParams::InstantiateWithInfer) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:45",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(45u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("insert_blindly: impl_def_id={0:?} st={1:?}",
impl_def_id, st) as &dyn Value))])
});
} else { ; }
};
self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
} else {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:48",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(48u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("insert_blindly: impl_def_id={0:?} st=None",
impl_def_id) as &dyn Value))])
});
} else { ; }
};
self.blanket_impls.push(impl_def_id)
}
}
#[doc = " Removes an impl from this set of children. Used when replacing"]
#[doc = " an impl with a parent. The impl must be present in the list of"]
#[doc = " children already."]
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
let vec: &mut Vec<DefId>;
if let Some(st) =
fast_reject::simplify_type(tcx, trait_ref.self_ty(),
TreatParams::InstantiateWithInfer) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:62",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(62u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("remove_existing: impl_def_id={0:?} st={1:?}",
impl_def_id, st) as &dyn Value))])
});
} else { ; }
};
vec = self.non_blanket_impls.get_mut(&st).unwrap();
} else {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:65",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(65u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("remove_existing: impl_def_id={0:?} st=None",
impl_def_id) as &dyn Value))])
});
} else { ; }
};
vec = &mut self.blanket_impls;
}
let index = vec.iter().position(|d| *d == impl_def_id).unwrap();
vec.remove(index);
}
#[doc =
" Attempt to insert an impl into this set of children, while comparing for"]
#[doc = " specialization relationships."]
fn insert(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId,
simplified_self: Option<SimplifiedType>, overlap_mode: OverlapMode)
-> Result<Inserted<'tcx>, OverlapError<'tcx>> {
{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("insert",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(75u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["impl_def_id",
"simplified_self", "overlap_mode"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&impl_def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&simplified_self)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&overlap_mode)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<Inserted<'tcx>, OverlapError<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
let mut last_lint = None;
let mut replace_children = Vec::new();
let possible_siblings =
match simplified_self {
Some(st) =>
PotentialSiblings::Filtered(filtered_children(self, st)),
None => PotentialSiblings::Unfiltered(iter_children(self)),
};
for possible_sibling in possible_siblings {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:92",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(92u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["possible_sibling"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&possible_sibling)
as &dyn Value))])
});
} else { ; }
};
let create_overlap_error =
|overlap: traits::coherence::OverlapResult<'tcx>|
{
let trait_ref = overlap.impl_header.trait_ref.unwrap();
let self_ty = trait_ref.self_ty();
OverlapError {
with_impl: possible_sibling,
trait_ref,
self_ty: self_ty.has_concrete_skeleton().then_some(self_ty),
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
involves_placeholder: overlap.involves_placeholder,
overflowing_predicates: overlap.overflowing_predicates,
}
};
let report_overlap_error =
|overlap: traits::coherence::OverlapResult<'tcx>,
last_lint: &mut _|
{
let should_err =
traits::overlapping_trait_impls(tcx, possible_sibling,
impl_def_id, traits::SkipLeakCheck::default(),
overlap_mode).is_some();
let error = create_overlap_error(overlap);
if should_err {
Err(error)
} else {
*last_lint =
Some(FutureCompatOverlapError {
error,
kind: FutureCompatOverlapErrorKind::LeakCheck,
});
Ok((false, false))
}
};
let last_lint_mut = &mut last_lint;
let (le, ge) =
traits::overlapping_trait_impls(tcx, possible_sibling,
impl_def_id, traits::SkipLeakCheck::Yes,
overlap_mode).map_or(Ok((false, false)),
|overlap|
{
if let Some(overlap_kind) =
tcx.impls_are_allowed_to_overlap(impl_def_id,
possible_sibling) {
match overlap_kind {
ty::ImplOverlapKind::Permitted { marker: _ } => {}
}
return Ok((false, false));
}
let le = tcx.specializes((impl_def_id, possible_sibling));
let ge = tcx.specializes((possible_sibling, impl_def_id));
if le == ge {
report_overlap_error(overlap, last_lint_mut)
} else { Ok((le, ge)) }
})?;
if le && !ge {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:165",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(165u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("descending as child of TraitRef {0:?}",
tcx.impl_trait_ref(possible_sibling).instantiate_identity())
as &dyn Value))])
});
} else { ; }
};
return Ok(Inserted::ShouldRecurseOn(possible_sibling));
} else if ge && !le {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:173",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(173u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("placing as parent of TraitRef {0:?}",
tcx.impl_trait_ref(possible_sibling).instantiate_identity())
as &dyn Value))])
});
} else { ; }
};
replace_children.push(possible_sibling);
} else {}
}
if !replace_children.is_empty() {
return Ok(Inserted::ReplaceChildren(replace_children));
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:190",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(190u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("placing as new sibling")
as &dyn Value))])
});
} else { ; }
};
self.insert_blindly(tcx, impl_def_id);
Ok(Inserted::BecameNewSibling(last_lint))
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:75",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(75u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["return"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&x) as
&dyn Value))])
});
} else { ; }
};
x
}
}#[extension(trait ChildrenExt<'tcx>)]
38impl<'tcx> Children {
39 fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
41 let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
42 if let Some(st) =
43 fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
44 {
45 debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
46 self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
47 } else {
48 debug!("insert_blindly: impl_def_id={:?} st=None", impl_def_id);
49 self.blanket_impls.push(impl_def_id)
50 }
51 }
52
53 fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
57 let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
58 let vec: &mut Vec<DefId>;
59 if let Some(st) =
60 fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
61 {
62 debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
63 vec = self.non_blanket_impls.get_mut(&st).unwrap();
64 } else {
65 debug!("remove_existing: impl_def_id={:?} st=None", impl_def_id);
66 vec = &mut self.blanket_impls;
67 }
68
69 let index = vec.iter().position(|d| *d == impl_def_id).unwrap();
70 vec.remove(index);
71 }
72
73 #[instrument(level = "debug", skip(self, tcx), ret)]
76 fn insert(
77 &mut self,
78 tcx: TyCtxt<'tcx>,
79 impl_def_id: DefId,
80 simplified_self: Option<SimplifiedType>,
81 overlap_mode: OverlapMode,
82 ) -> Result<Inserted<'tcx>, OverlapError<'tcx>> {
83 let mut last_lint = None;
84 let mut replace_children = Vec::new();
85
86 let possible_siblings = match simplified_self {
87 Some(st) => PotentialSiblings::Filtered(filtered_children(self, st)),
88 None => PotentialSiblings::Unfiltered(iter_children(self)),
89 };
90
91 for possible_sibling in possible_siblings {
92 debug!(?possible_sibling);
93
94 let create_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>| {
95 let trait_ref = overlap.impl_header.trait_ref.unwrap();
96 let self_ty = trait_ref.self_ty();
97
98 OverlapError {
99 with_impl: possible_sibling,
100 trait_ref,
101 self_ty: self_ty.has_concrete_skeleton().then_some(self_ty),
105 intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
106 involves_placeholder: overlap.involves_placeholder,
107 overflowing_predicates: overlap.overflowing_predicates,
108 }
109 };
110
111 let report_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>,
112 last_lint: &mut _| {
113 let should_err = traits::overlapping_trait_impls(
117 tcx,
118 possible_sibling,
119 impl_def_id,
120 traits::SkipLeakCheck::default(),
121 overlap_mode,
122 )
123 .is_some();
124
125 let error = create_overlap_error(overlap);
126
127 if should_err {
128 Err(error)
129 } else {
130 *last_lint = Some(FutureCompatOverlapError {
131 error,
132 kind: FutureCompatOverlapErrorKind::LeakCheck,
133 });
134
135 Ok((false, false))
136 }
137 };
138
139 let last_lint_mut = &mut last_lint;
140 let (le, ge) = traits::overlapping_trait_impls(
141 tcx,
142 possible_sibling,
143 impl_def_id,
144 traits::SkipLeakCheck::Yes,
145 overlap_mode,
146 )
147 .map_or(Ok((false, false)), |overlap| {
148 if let Some(overlap_kind) =
149 tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
150 {
151 match overlap_kind {
152 ty::ImplOverlapKind::Permitted { marker: _ } => {}
153 }
154
155 return Ok((false, false));
156 }
157
158 let le = tcx.specializes((impl_def_id, possible_sibling));
159 let ge = tcx.specializes((possible_sibling, impl_def_id));
160
161 if le == ge { report_overlap_error(overlap, last_lint_mut) } else { Ok((le, ge)) }
162 })?;
163
164 if le && !ge {
165 debug!(
166 "descending as child of TraitRef {:?}",
167 tcx.impl_trait_ref(possible_sibling).instantiate_identity()
168 );
169
170 return Ok(Inserted::ShouldRecurseOn(possible_sibling));
172 } else if ge && !le {
173 debug!(
174 "placing as parent of TraitRef {:?}",
175 tcx.impl_trait_ref(possible_sibling).instantiate_identity()
176 );
177
178 replace_children.push(possible_sibling);
179 } else {
180 }
183 }
184
185 if !replace_children.is_empty() {
186 return Ok(Inserted::ReplaceChildren(replace_children));
187 }
188
189 debug!("placing as new sibling");
191 self.insert_blindly(tcx, impl_def_id);
192 Ok(Inserted::BecameNewSibling(last_lint))
193 }
194}
195
196fn iter_children(children: &Children) -> impl Iterator<Item = DefId> {
197 let nonblanket = children.non_blanket_impls.iter().flat_map(|(_, v)| v.iter());
198 children.blanket_impls.iter().chain(nonblanket).cloned()
199}
200
201fn filtered_children(children: &mut Children, st: SimplifiedType) -> impl Iterator<Item = DefId> {
202 let nonblanket = children.non_blanket_impls.entry(st).or_default().iter();
203 children.blanket_impls.iter().chain(nonblanket).cloned()
204}
205
206enum PotentialSiblings<I, J>
208where
209 I: Iterator<Item = DefId>,
210 J: Iterator<Item = DefId>,
211{
212 Unfiltered(I),
213 Filtered(J),
214}
215
216impl<I, J> Iterator for PotentialSiblings<I, J>
217where
218 I: Iterator<Item = DefId>,
219 J: Iterator<Item = DefId>,
220{
221 type Item = DefId;
222
223 fn next(&mut self) -> Option<Self::Item> {
224 match *self {
225 PotentialSiblings::Unfiltered(ref mut iter) => iter.next(),
226 PotentialSiblings::Filtered(ref mut iter) => iter.next(),
227 }
228 }
229}
230
231impl<'tcx> GraphExt<'tcx> for Graph {
#[doc =
" Insert a local impl into the specialization graph. If an existing impl"]
#[doc =
" conflicts with it (has overlap, but neither specializes the other),"]
#[doc =
" information about the area of overlap is returned in the `Err`."]
fn insert(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId,
overlap_mode: OverlapMode)
->
Result<Option<FutureCompatOverlapError<'tcx>>,
OverlapError<'tcx>> {
if !impl_def_id.is_local() {
::core::panicking::panic("assertion failed: impl_def_id.is_local()")
};
let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
let trait_def_id = trait_ref.def_id;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:248",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(248u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("insert({0:?}): inserting TraitRef {1:?} into specialization graph",
impl_def_id, trait_ref) as &dyn Value))])
});
} else { ; }
};
if trait_ref.references_error() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs:258",
"rustc_trait_selection::traits::specialize::specialization_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs"),
::tracing_core::__macro_support::Option::Some(258u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::specialize::specialization_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("insert: inserting dummy node for erroneous TraitRef {0:?}, impl_def_id={1:?}, trait_def_id={2:?}",
trait_ref, impl_def_id, trait_def_id) as &dyn Value))])
});
} else { ; }
};
self.parent.insert(impl_def_id, trait_def_id);
self.children.entry(trait_def_id).or_default().insert_blindly(tcx,
impl_def_id);
return Ok(None);
}
let mut parent = trait_def_id;
let mut last_lint = None;
let simplified =
fast_reject::simplify_type(tcx, trait_ref.self_ty(),
TreatParams::InstantiateWithInfer);
loop {
let insert_result =
self.children.entry(parent).or_default().insert(tcx,
impl_def_id, simplified, overlap_mode)?;
match insert_result {
Inserted::BecameNewSibling(opt_lint) => {
last_lint = opt_lint;
break;
}
Inserted::ReplaceChildren(grand_children_to_be) => {
{
let siblings = self.children.get_mut(&parent).unwrap();
for &grand_child_to_be in &grand_children_to_be {
siblings.remove_existing(tcx, grand_child_to_be);
}
siblings.insert_blindly(tcx, impl_def_id);
}
for &grand_child_to_be in &grand_children_to_be {
self.parent.insert(grand_child_to_be, impl_def_id);
}
self.parent.insert(impl_def_id, parent);
for &grand_child_to_be in &grand_children_to_be {
self.children.entry(impl_def_id).or_default().insert_blindly(tcx,
grand_child_to_be);
}
break;
}
Inserted::ShouldRecurseOn(new_parent) => {
parent = new_parent;
}
}
}
self.parent.insert(impl_def_id, parent);
Ok(last_lint)
}
#[doc =
" Insert cached metadata mapping from a child impl back to its parent."]
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId,
child: DefId) {
if self.parent.insert(child, parent).is_some() {
::rustc_middle::util::bug::bug_fmt(format_args!("When recording an impl from the crate store, information about its parent was already present."));
}
self.children.entry(parent).or_default().insert_blindly(tcx, child);
}
}#[extension(pub trait GraphExt<'tcx>)]
232impl<'tcx> Graph {
233 fn insert(
237 &mut self,
238 tcx: TyCtxt<'tcx>,
239 impl_def_id: DefId,
240 overlap_mode: OverlapMode,
241 ) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>> {
242 assert!(impl_def_id.is_local());
243
244 let trait_ref = tcx.impl_trait_ref(impl_def_id).skip_binder();
246 let trait_def_id = trait_ref.def_id;
247
248 debug!(
249 "insert({:?}): inserting TraitRef {:?} into specialization graph",
250 impl_def_id, trait_ref
251 );
252
253 if trait_ref.references_error() {
258 debug!(
259 "insert: inserting dummy node for erroneous TraitRef {:?}, \
260 impl_def_id={:?}, trait_def_id={:?}",
261 trait_ref, impl_def_id, trait_def_id
262 );
263
264 self.parent.insert(impl_def_id, trait_def_id);
265 self.children.entry(trait_def_id).or_default().insert_blindly(tcx, impl_def_id);
266 return Ok(None);
267 }
268
269 let mut parent = trait_def_id;
270 let mut last_lint = None;
271 let simplified =
272 fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer);
273
274 loop {
276 let insert_result = self.children.entry(parent).or_default().insert(
277 tcx,
278 impl_def_id,
279 simplified,
280 overlap_mode,
281 )?;
282
283 match insert_result {
284 Inserted::BecameNewSibling(opt_lint) => {
285 last_lint = opt_lint;
286 break;
287 }
288 Inserted::ReplaceChildren(grand_children_to_be) => {
289 {
305 let siblings = self.children.get_mut(&parent).unwrap();
306 for &grand_child_to_be in &grand_children_to_be {
307 siblings.remove_existing(tcx, grand_child_to_be);
308 }
309 siblings.insert_blindly(tcx, impl_def_id);
310 }
311
312 for &grand_child_to_be in &grand_children_to_be {
314 self.parent.insert(grand_child_to_be, impl_def_id);
315 }
316 self.parent.insert(impl_def_id, parent);
317
318 for &grand_child_to_be in &grand_children_to_be {
320 self.children
321 .entry(impl_def_id)
322 .or_default()
323 .insert_blindly(tcx, grand_child_to_be);
324 }
325 break;
326 }
327 Inserted::ShouldRecurseOn(new_parent) => {
328 parent = new_parent;
329 }
330 }
331 }
332
333 self.parent.insert(impl_def_id, parent);
334 Ok(last_lint)
335 }
336
337 fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId) {
339 if self.parent.insert(child, parent).is_some() {
340 bug!(
341 "When recording an impl from the crate store, information about its parent \
342 was already present."
343 );
344 }
345
346 self.children.entry(parent).or_default().insert_blindly(tcx, child);
347 }
348}
349
350pub(crate) fn assoc_def(
353 tcx: TyCtxt<'_>,
354 impl_def_id: DefId,
355 assoc_def_id: DefId,
356) -> Result<LeafDef, ErrorGuaranteed> {
357 let trait_def_id = tcx.impl_trait_id(impl_def_id);
358 let trait_def = tcx.trait_def(trait_def_id);
359
360 if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_def_id) {
367 if let Some(impl_def_id) = impl_def_id.as_local() {
370 tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
371 }
372
373 let item = tcx.associated_item(impl_item_id);
374 let impl_node = Node::Impl(impl_def_id);
375 return Ok(LeafDef {
376 item,
377 defining_node: impl_node,
378 finalizing_node: if item.defaultness(tcx).is_default() {
379 None
380 } else {
381 Some(impl_node)
382 },
383 });
384 }
385
386 let ancestors = trait_def.ancestors(tcx, impl_def_id)?;
387 if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
388 if let ty::AssocContainer::TraitImpl(_) = assoc_item.item.container
391 && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
392 {
393 tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
394 }
395
396 Ok(assoc_item)
397 } else {
398 ::rustc_middle::util::bug::bug_fmt(format_args!("No associated type `{0}` for {1}",
tcx.item_name(assoc_def_id), tcx.def_path_str(impl_def_id)))bug!(
405 "No associated type `{}` for {}",
406 tcx.item_name(assoc_def_id),
407 tcx.def_path_str(impl_def_id)
408 )
409 }
410}