1use std::ops::ControlFlow;
8
9use rustc_attr_ir::lang_items::LangItem;
10use rustc_errors::FatalError;
11use rustc_hir as hir;
12use rustc_hir::def_id::DefId;
13use rustc_middle::query::Providers;
14use rustc_middle::ty::{
15 self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
16 TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized,
17 Upcast, elaborate,
18};
19use rustc_span::{DUMMY_SP, Span, kw, sym};
20use smallvec::SmallVec;
21use tracing::{debug, instrument};
22
23use super::elaborate;
24use crate::infer::TyCtxtInferExt;
25pub use crate::traits::DynCompatibilityViolation;
26use crate::traits::query::evaluate_obligation::InferCtxtExt;
27use crate::traits::{
28 AssocConstViolation, MethodViolation, Obligation, ObligationCause,
29 normalize_param_env_or_error, util,
30};
31
32{}
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("hir_ty_lowering_dyn_compatibility_violations",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(37u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("trait_def_id")
}> =
::tracing::__macro_support::FieldName::new("trait_def_id");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_def_id)
as &dyn ::tracing::field::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:
Vec<DynCompatibilityViolation> = loop {};
return __tracing_attr_fake_return;
}
{
if true {
if !tcx.generics_of(trait_def_id).has_self {
::core::panicking::panic("assertion failed: tcx.generics_of(trait_def_id).has_self")
};
};
elaborate::supertrait_def_ids(tcx,
trait_def_id).map(|def_id|
clauses_reference_self(tcx, def_id,
true)).filter(|spans|
!spans.is_empty()).map(DynCompatibilityViolation::SupertraitSelf).collect()
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:37",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(37u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
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(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(tcx), ret)]
38pub fn hir_ty_lowering_dyn_compatibility_violations(
39 tcx: TyCtxt<'_>,
40 trait_def_id: DefId,
41) -> Vec<DynCompatibilityViolation> {
42 debug_assert!(tcx.generics_of(trait_def_id).has_self);
43 elaborate::supertrait_def_ids(tcx, trait_def_id)
44 .map(|def_id| clauses_reference_self(tcx, def_id, true))
45 .filter(|spans| !spans.is_empty())
46 .map(DynCompatibilityViolation::SupertraitSelf)
47 .collect()
48}
49
50fn dyn_compatibility_violations(
51 tcx: TyCtxt<'_>,
52 trait_def_id: DefId,
53) -> &'_ [DynCompatibilityViolation] {
54 if true {
if !tcx.generics_of(trait_def_id).has_self {
::core::panicking::panic("assertion failed: tcx.generics_of(trait_def_id).has_self")
};
};debug_assert!(tcx.generics_of(trait_def_id).has_self);
55 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:55",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(55u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("dyn_compatibility_violations: {0:?}",
trait_def_id) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("dyn_compatibility_violations: {:?}", trait_def_id);
56 tcx.arena.alloc_from_iter(
57 elaborate::supertrait_def_ids(tcx, trait_def_id)
58 .flat_map(|def_id| dyn_compatibility_violations_for_trait(tcx, def_id)),
59 )
60}
61
62fn is_dyn_compatible(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
63 tcx.dyn_compatibility_violations(trait_def_id).is_empty()
64}
65
66pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::AssocItem) -> bool {
71 if true {
if !tcx.generics_of(trait_def_id).has_self {
::core::panicking::panic("assertion failed: tcx.generics_of(trait_def_id).has_self")
};
};debug_assert!(tcx.generics_of(trait_def_id).has_self);
72 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:72",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(72u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("is_vtable_safe_method({0:?}, {1:?})",
trait_def_id, method) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
73 if tcx.generics_require_sized_self(method.def_id) {
75 return false;
76 }
77
78 virtual_call_violations_for_method(tcx, trait_def_id, method).is_empty()
79}
80
81{}
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("dyn_compatibility_violations_for_trait",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(81u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("trait_def_id")
}> =
::tracing::__macro_support::FieldName::new("trait_def_id");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_def_id)
as &dyn ::tracing::field::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:
Vec<DynCompatibilityViolation> = loop {};
return __tracing_attr_fake_return;
}
{
let mut violations: Vec<_> =
tcx.associated_items(trait_def_id).in_definition_order().flat_map(|&item|
dyn_compatibility_violations_for_assoc_item(tcx,
trait_def_id, item)).collect();
if trait_has_sized_self(tcx, trait_def_id) {
let spans = get_sized_bounds(tcx, trait_def_id);
violations.push(DynCompatibilityViolation::SizedSelf(spans));
} else if let Some(span) =
tcx.trait_def(trait_def_id).force_dyn_incompatible {
violations.push(DynCompatibilityViolation::ExplicitlyDynIncompatible([span].into()));
}
let spans =
clauses_reference_self(tcx, trait_def_id, false);
if !spans.is_empty() {
violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
}
let spans = bounds_reference_self(tcx, trait_def_id);
if !spans.is_empty() {
violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
}
let spans =
super_clauses_have_non_lifetime_binders(tcx, trait_def_id);
if !spans.is_empty() {
violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
}
let spans =
super_clauses_are_unconditionally_const(tcx, trait_def_id);
if !spans.is_empty() {
violations.push(DynCompatibilityViolation::SupertraitConst(spans));
}
violations
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:81",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(81u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
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(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(tcx), ret)]
82fn dyn_compatibility_violations_for_trait(
83 tcx: TyCtxt<'_>,
84 trait_def_id: DefId,
85) -> Vec<DynCompatibilityViolation> {
86 let mut violations: Vec<_> = tcx
88 .associated_items(trait_def_id)
89 .in_definition_order()
90 .flat_map(|&item| dyn_compatibility_violations_for_assoc_item(tcx, trait_def_id, item))
91 .collect();
92
93 if trait_has_sized_self(tcx, trait_def_id) {
95 let spans = get_sized_bounds(tcx, trait_def_id);
97 violations.push(DynCompatibilityViolation::SizedSelf(spans));
98 } else if let Some(span) = tcx.trait_def(trait_def_id).force_dyn_incompatible {
99 violations.push(DynCompatibilityViolation::ExplicitlyDynIncompatible([span].into()));
100 }
101
102 let spans = clauses_reference_self(tcx, trait_def_id, false);
103 if !spans.is_empty() {
104 violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
105 }
106 let spans = bounds_reference_self(tcx, trait_def_id);
107 if !spans.is_empty() {
108 violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
109 }
110 let spans = super_clauses_have_non_lifetime_binders(tcx, trait_def_id);
111 if !spans.is_empty() {
112 violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
113 }
114 let spans = super_clauses_are_unconditionally_const(tcx, trait_def_id);
115 if !spans.is_empty() {
116 violations.push(DynCompatibilityViolation::SupertraitConst(spans));
117 }
118
119 violations
120}
121
122fn sized_trait_bound_spans<'tcx>(
123 tcx: TyCtxt<'tcx>,
124 bounds: hir::GenericBounds<'tcx>,
125) -> impl 'tcx + Iterator<Item = Span> {
126 bounds.iter().filter_map(move |b| match b {
127 hir::GenericBound::Trait(trait_ref)
128 if trait_has_sized_self(
129 tcx,
130 trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
131 ) =>
132 {
133 Some(trait_ref.span)
135 }
136 _ => None,
137 })
138}
139
140fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> {
141 tcx.hir_get_if_local(trait_def_id)
142 .and_then(|node| match node {
143 hir::Node::Item(hir::Item {
144 kind: hir::ItemKind::Trait { generics, bounds, .. },
145 ..
146 }) => Some(
147 generics
148 .predicates
149 .iter()
150 .filter_map(|pred| {
151 match pred.kind {
152 hir::WherePredicateKind::BoundPredicate(pred)
153 if pred.bounded_ty.hir_id.owner.to_def_id() == trait_def_id =>
154 {
155 Some(sized_trait_bound_spans(tcx, pred.bounds))
158 }
159 _ => None,
160 }
161 })
162 .flatten()
163 .chain(sized_trait_bound_spans(tcx, bounds))
165 .collect::<SmallVec<[Span; 1]>>(),
166 ),
167 _ => None,
168 })
169 .unwrap_or_else(SmallVec::new)
170}
171
172fn clauses_reference_self(
173 tcx: TyCtxt<'_>,
174 trait_def_id: DefId,
175 supertraits_only: bool,
176) -> SmallVec<[Span; 1]> {
177 let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
178 let clauses = if supertraits_only {
179 tcx.explicit_super_clauses_of(trait_def_id).skip_binder()
180 } else {
181 tcx.clauses_of(trait_def_id).clauses
182 };
183 clauses
184 .iter()
185 .map(|&(clause, sp)| (clause.instantiate_supertrait(tcx, trait_ref), sp))
186 .filter_map(|(clause, sp)| {
187 predicate_references_self(tcx, trait_def_id, clause, sp, AllowSelfProjections::No)
192 })
193 .collect()
194}
195
196fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> {
197 tcx.associated_items(trait_def_id)
198 .in_definition_order()
199 .filter(|item| item.is_type())
201 .filter(|item| !tcx.generics_require_sized_self(item.def_id))
203 .flat_map(|item| {
204 tcx.explicit_item_bounds(item.def_id)
205 .iter_identity_copied()
206 .map(Unnormalized::skip_norm_wip)
207 })
208 .filter_map(|(clause, sp)| {
209 predicate_references_self(tcx, trait_def_id, clause, sp, AllowSelfProjections::Yes)
212 })
213 .collect()
214}
215
216fn predicate_references_self<'tcx>(
217 tcx: TyCtxt<'tcx>,
218 trait_def_id: DefId,
219 predicate: ty::Clause<'tcx>,
220 sp: Span,
221 allow_self_projections: AllowSelfProjections,
222) -> Option<Span> {
223 match predicate.kind().skip_binder() {
224 ty::ClauseKind::Trait(ref data) => {
225 data.trait_ref.args.as_slice()[1..]
227 .iter()
228 .any(|&arg| {
229 contains_illegal_self_type_reference(
230 tcx,
231 trait_def_id,
232 arg,
233 allow_self_projections,
234 )
235 })
236 .then_some(sp)
237 }
238 ty::ClauseKind::Projection(ref data) => {
239 data.projection_term.args.as_slice()[1..]
255 .iter()
256 .any(|&arg| {
257 contains_illegal_self_type_reference(
258 tcx,
259 trait_def_id,
260 arg,
261 allow_self_projections,
262 )
263 })
264 .then_some(sp)
265 }
266 ty::ClauseKind::ConstArgHasType(_ct, ty) => {
267 contains_illegal_self_type_reference(tcx, trait_def_id, ty, allow_self_projections)
268 .then_some(sp)
269 }
270
271 ty::ClauseKind::WellFormed(..)
272 | ty::ClauseKind::TypeOutlives(..)
273 | ty::ClauseKind::RegionOutlives(..)
274 | ty::ClauseKind::HostEffect(..)
275 | ty::ClauseKind::UnstableFeature(_) => None,
276
277 ty::ClauseKind::ConstEvaluatable(..) => None,
279 }
280}
281
282fn super_clauses_have_non_lifetime_binders(
283 tcx: TyCtxt<'_>,
284 trait_def_id: DefId,
285) -> SmallVec<[Span; 1]> {
286 tcx.explicit_super_clauses_of(trait_def_id)
287 .iter_identity_copied()
288 .map(Unnormalized::skip_norm_wip)
289 .filter_map(|(clause, span)| clause.has_non_region_bound_vars().then_some(span))
290 .collect()
291}
292
293fn super_clauses_are_unconditionally_const(
297 tcx: TyCtxt<'_>,
298 trait_def_id: DefId,
299) -> SmallVec<[Span; 1]> {
300 tcx.explicit_super_clauses_of(trait_def_id)
301 .iter_identity_copied()
302 .map(Unnormalized::skip_norm_wip)
303 .filter_map(|(clause, span)| {
304 if let ty::ClauseKind::HostEffect(_) = clause.kind().skip_binder() {
305 Some(span)
306 } else {
307 None
308 }
309 })
310 .collect()
311}
312
313fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
314 tcx.generics_require_sized_self(trait_def_id)
315}
316
317fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
318 let Some(sized_def_id) = tcx.lang_items().sized_trait() else {
319 return false; };
321
322 let clauses: Vec<_> = tcx
324 .clauses_of(def_id)
325 .instantiate_identity(tcx)
326 .clauses
327 .into_iter()
328 .map(Unnormalized::skip_norm_wip)
329 .collect();
330 elaborate(tcx, clauses).any(|clause| match clause.kind().skip_binder() {
331 ty::ClauseKind::Trait(ref trait_pred) => {
332 trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
333 }
334 ty::ClauseKind::RegionOutlives(_)
335 | ty::ClauseKind::TypeOutlives(_)
336 | ty::ClauseKind::Projection(_)
337 | ty::ClauseKind::ConstArgHasType(_, _)
338 | ty::ClauseKind::WellFormed(_)
339 | ty::ClauseKind::ConstEvaluatable(_)
340 | ty::ClauseKind::UnstableFeature(_)
341 | ty::ClauseKind::HostEffect(..) => false,
342 })
343}
344
345{}
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("dyn_compatibility_violations_for_assoc_item",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(345u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("trait_def_id")
}> =
::tracing::__macro_support::FieldName::new("trait_def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("item")
}> =
::tracing::__macro_support::FieldName::new("item");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&item)
as &dyn ::tracing::field::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:
Vec<DynCompatibilityViolation> = loop {};
return __tracing_attr_fake_return;
}
{
if tcx.defaultness(item.def_id).is_final() {
return Vec::new();
}
if tcx.generics_require_sized_self(item.def_id) {
return Vec::new();
}
let span = || item.ident(tcx).span;
match item.kind {
ty::AssocKind::Const { data: ty::AssocConstData::Anonymous }
=> {
{
::core::panicking::panic_fmt(format_args!("anonymous associated consts shouldn\'t end up here"));
}
}
ty::AssocKind::Const { data: ty::AssocConstData::Named(name)
} => {
let mut errors = Vec::new();
if tcx.features().gca_min_const_items() {
if !tcx.generics_of(item.def_id).is_own_empty() {
errors.push(AssocConstViolation::Generic);
} else if !tcx.is_always_gca(item.def_id) &&
!tcx.features().gca_const_items() {
errors.push(AssocConstViolation::NonType);
}
let ty =
ty::Binder::dummy(tcx.type_of(item.def_id).instantiate_identity().skip_norm_wip());
if contains_illegal_self_type_reference(tcx, trait_def_id,
ty, AllowSelfProjections::Yes) {
errors.push(AssocConstViolation::TypeReferencesSelf);
}
} else {
errors.push(AssocConstViolation::FeatureNotEnabled);
}
errors.into_iter().map(|error|
DynCompatibilityViolation::AssocConst(name, error,
span())).collect()
}
ty::AssocKind::Fn { name, .. } => {
virtual_call_violations_for_method(tcx, trait_def_id,
item).into_iter().map(|v|
{
let node = tcx.hir_get_if_local(item.def_id);
let span =
match (&v, node) {
(MethodViolation::ReferencesSelfInput(Some(span)), _) =>
*span,
(MethodViolation::UndispatchableReceiver(Some((span, _))),
_) => *span,
(MethodViolation::ReferencesImplTraitInTrait(span), _) =>
*span,
(MethodViolation::ReferencesSelfOutput, Some(node)) => {
node.fn_decl().map_or(item.ident(tcx).span,
|decl| decl.output.span())
}
_ => span(),
};
DynCompatibilityViolation::Method(name, v, span)
}).collect()
}
ty::AssocKind::Type { data } => {
if !tcx.generics_of(item.def_id).is_own_empty() &&
let ty::AssocTypeData::Normal(name) = data {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[DynCompatibilityViolation::GenericAssocTy(name, span())]))
} else { Vec::new() }
}
}
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:345",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(345u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
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(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(tcx), ret)]
346pub fn dyn_compatibility_violations_for_assoc_item(
347 tcx: TyCtxt<'_>,
348 trait_def_id: DefId,
349 item: ty::AssocItem,
350) -> Vec<DynCompatibilityViolation> {
351 if tcx.defaultness(item.def_id).is_final() {
353 return Vec::new();
354 }
355
356 if tcx.generics_require_sized_self(item.def_id) {
358 return Vec::new();
359 }
360
361 let span = || item.ident(tcx).span;
362
363 match item.kind {
364 ty::AssocKind::Const { data: ty::AssocConstData::Anonymous } => {
365 panic!("anonymous associated consts shouldn't end up here")
366 }
367 ty::AssocKind::Const { data: ty::AssocConstData::Named(name) } => {
368 let mut errors = Vec::new();
373
374 if tcx.features().gca_min_const_items() {
375 if !tcx.generics_of(item.def_id).is_own_empty() {
376 errors.push(AssocConstViolation::Generic);
377 } else if !tcx.is_always_gca(item.def_id) && !tcx.features().gca_const_items() {
378 errors.push(AssocConstViolation::NonType);
379 }
380
381 let ty = ty::Binder::dummy(
382 tcx.type_of(item.def_id).instantiate_identity().skip_norm_wip(),
383 );
384 if contains_illegal_self_type_reference(
385 tcx,
386 trait_def_id,
387 ty,
388 AllowSelfProjections::Yes,
389 ) {
390 errors.push(AssocConstViolation::TypeReferencesSelf);
391 }
392 } else {
393 errors.push(AssocConstViolation::FeatureNotEnabled);
394 }
395
396 errors
397 .into_iter()
398 .map(|error| DynCompatibilityViolation::AssocConst(name, error, span()))
399 .collect()
400 }
401 ty::AssocKind::Fn { name, .. } => {
402 virtual_call_violations_for_method(tcx, trait_def_id, item)
403 .into_iter()
404 .map(|v| {
405 let node = tcx.hir_get_if_local(item.def_id);
406 let span = match (&v, node) {
408 (MethodViolation::ReferencesSelfInput(Some(span)), _) => *span,
409 (MethodViolation::UndispatchableReceiver(Some((span, _))), _) => *span,
410 (MethodViolation::ReferencesImplTraitInTrait(span), _) => *span,
411 (MethodViolation::ReferencesSelfOutput, Some(node)) => {
412 node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span())
413 }
414 _ => span(),
415 };
416
417 DynCompatibilityViolation::Method(name, v, span)
418 })
419 .collect()
420 }
421 ty::AssocKind::Type { data } => {
422 if !tcx.generics_of(item.def_id).is_own_empty()
423 && let ty::AssocTypeData::Normal(name) = data
424 {
425 vec![DynCompatibilityViolation::GenericAssocTy(name, span())]
426 } else {
427 Vec::new()
431 }
432 }
433 }
434}
435
436fn virtual_call_violations_for_method<'tcx>(
441 tcx: TyCtxt<'tcx>,
442 trait_def_id: DefId,
443 method: ty::AssocItem,
444) -> Vec<MethodViolation> {
445 let sig = tcx.fn_sig(method.def_id).instantiate_identity().skip_norm_wip();
446
447 if !method.is_method() {
449 let sugg = if let Some(hir::Node::TraitItem(hir::TraitItem {
450 generics,
451 kind: hir::TraitItemKind::Fn(sig, _),
452 ..
453 })) = tcx.hir_get_if_local(method.def_id).as_ref()
454 {
455 let sm = tcx.sess.source_map();
456 Some((
457 (
458 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("&self{0}",
if sig.decl.inputs.is_empty() { "" } else { ", " }))
})format!("&self{}", if sig.decl.inputs.is_empty() { "" } else { ", " }),
459 sm.span_through_char(sig.span, '(').shrink_to_hi(),
460 ),
461 (
462 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} Self: Sized",
generics.add_where_or_trailing_comma()))
})format!("{} Self: Sized", generics.add_where_or_trailing_comma()),
463 generics.tail_span_for_predicate_suggestion(),
464 ),
465 ))
466 } else {
467 None
468 };
469
470 return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[MethodViolation::StaticMethod(sugg)]))vec![MethodViolation::StaticMethod(sugg)];
473 }
474
475 let mut errors = Vec::new();
476
477 for (i, &input_ty) in sig.skip_binder().inputs().iter().enumerate().skip(1) {
478 if contains_illegal_self_type_reference(
479 tcx,
480 trait_def_id,
481 sig.rebind(input_ty),
482 AllowSelfProjections::Yes,
483 ) {
484 let span = if let Some(hir::Node::TraitItem(hir::TraitItem {
485 kind: hir::TraitItemKind::Fn(sig, _),
486 ..
487 })) = tcx.hir_get_if_local(method.def_id).as_ref()
488 {
489 Some(sig.decl.inputs[i].span)
490 } else {
491 None
492 };
493 errors.push(MethodViolation::ReferencesSelfInput(span));
494 }
495 }
496 if contains_illegal_self_type_reference(
497 tcx,
498 trait_def_id,
499 sig.output(),
500 AllowSelfProjections::Yes,
501 ) {
502 errors.push(MethodViolation::ReferencesSelfOutput);
503 }
504 if let Some(error) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
505 errors.push(error);
506 }
507 if sig.skip_binder().c_variadic() {
508 errors.push(MethodViolation::CVariadic);
509 }
510
511 let own_counts = tcx.generics_of(method.def_id).own_counts();
513 if own_counts.types > 0 || own_counts.consts > 0 {
514 errors.push(MethodViolation::Generic);
515 }
516
517 let receiver_ty = tcx.liberate_late_bound_regions(method.def_id, sig.input(0));
518
519 if receiver_ty != tcx.types.self_param {
524 if !receiver_is_dispatchable(tcx, method, receiver_ty) {
525 let span_n_lt = if let Some(hir::Node::TraitItem(hir::TraitItem {
526 kind: hir::TraitItemKind::Fn(sig, trait_fn),
527 ..
528 })) = tcx.hir_get_if_local(method.def_id).as_ref()
529 {
530 let lt = match sig.decl.inputs[0].kind {
532 hir::TyKind::Ref(lt, ..) if lt.ident.name == kw::UnderscoreLifetime => {
533 sym::empty
534 }
535 hir::TyKind::Ref(lt, ..) => lt.ident.name,
536 _ => sym::empty,
537 };
538 match trait_fn {
540 hir::TraitFn::Required([Some(name), ..])
541 if name.span.ctxt() == sig.decl.inputs[0].span.ctxt() =>
542 {
543 Some(name.span.to(sig.decl.inputs[0].span))
544 }
545 hir::TraitFn::Provided(body_id)
546 if let body = tcx.hir_body(*body_id)
547 && let Some(p) = body.params.get(0)
548 && p.span.ctxt() == p.ty_span.ctxt() =>
549 {
550 Some(p.span.to(p.ty_span))
551 }
552 _ => None,
553 }
554 .map(|sp| (sp, lt))
555 } else {
556 None
557 };
558 errors.push(MethodViolation::UndispatchableReceiver(span_n_lt));
559 } else {
560 }
563 }
564
565 if tcx.clauses_of(method.def_id).clauses.iter().any(|&(clause, _span)| {
568 if clause.as_type_outlives_clause().is_some() {
578 return false;
579 }
580
581 if let ty::ClauseKind::Trait(ty::TraitClause {
595 trait_ref: pred_trait_ref,
596 polarity: ty::ClausePolarity::Positive,
597 }) = clause.kind().skip_binder()
598 && pred_trait_ref.self_ty() == tcx.types.self_param
599 && tcx.trait_is_auto(pred_trait_ref.def_id)
600 {
601 if pred_trait_ref.args.len() != 1 {
606 if !tcx.dcx().has_errors().is_some() {
{
::core::panicking::panic_fmt(format_args!("auto traits cannot have generic parameters"));
}
};assert!(
607 tcx.dcx().has_errors().is_some(),
608 "auto traits cannot have generic parameters"
609 );
610 }
611 return false;
612 }
613
614 contains_illegal_self_type_reference(tcx, trait_def_id, clause, AllowSelfProjections::Yes)
615 }) {
616 errors.push(MethodViolation::WhereClauseReferencesSelf);
617 }
618
619 errors
620}
621
622fn receiver_for_self_ty<'tcx>(
625 tcx: TyCtxt<'tcx>,
626 receiver_ty: Ty<'tcx>,
627 self_ty: Ty<'tcx>,
628 method_def_id: DefId,
629) -> Ty<'tcx> {
630 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:630",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(630u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("receiver_for_self_ty({0:?}, {1:?}, {2:?})",
receiver_ty, self_ty, method_def_id) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
631 let args = GenericArgs::for_item(tcx, method_def_id, |param, _| {
632 if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) }
633 });
634
635 let result = EarlyBinder::bind(tcx, receiver_ty).instantiate(tcx, args).skip_norm_wip();
636 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:636",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(636u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("receiver_for_self_ty({0:?}, {1:?}, {2:?}) = {3:?}",
receiver_ty, self_ty, method_def_id, result) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
637 "receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
638 receiver_ty, self_ty, method_def_id, result
639 );
640 result
641}
642
643fn receiver_is_dispatchable<'tcx>(
693 tcx: TyCtxt<'tcx>,
694 method: ty::AssocItem,
695 receiver_ty: Ty<'tcx>,
696) -> bool {
697 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:697",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(697u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("receiver_is_dispatchable: method = {0:?}, receiver_ty = {1:?}",
method, receiver_ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("receiver_is_dispatchable: method = {:?}, receiver_ty = {:?}", method, receiver_ty);
698
699 if receiver_ty.references_error() {
700 return false;
701 }
702
703 let (Some(unsize_did), Some(dispatch_from_dyn_did)) =
704 (tcx.lang_items().unsize_trait(), tcx.lang_items().dispatch_from_dyn_trait())
705 else {
706 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs:706",
"rustc_trait_selection::traits::dyn_compatibility",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5f4effd579500175af844241eb179e756190f1e7/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs"),
::tracing_core::__macro_support::Option::Some(706u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::dyn_compatibility"),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("receiver_is_dispatchable: Missing `Unsize` or `DispatchFromDyn` traits");
707 return false;
708 };
709
710 let unsized_self_ty: Ty<'tcx> =
713 Ty::new_param(tcx, u32::MAX, rustc_span::sym::RustaceansAreAwesome);
714
715 let unsized_receiver_ty =
717 receiver_for_self_ty(tcx, receiver_ty, unsized_self_ty, method.def_id);
718
719 let param_env = {
722 let mut clauses: Vec<_> = tcx
735 .clauses_of(method.def_id)
736 .instantiate_identity(tcx)
737 .clauses
738 .into_iter()
739 .map(Unnormalized::skip_norm_wip)
740 .collect();
741
742 let unsize_predicate =
744 ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]);
745 clauses.push(unsize_predicate.upcast(tcx));
746
747 let trait_def_id = method.trait_container(tcx).unwrap();
749 let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
750 if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
751 });
752 let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
753 clauses.push(trait_predicate.upcast(tcx));
754
755 clauses.extend(
760 tcx.clauses_of(trait_def_id)
761 .instantiate(tcx, args)
762 .clauses
763 .into_iter()
764 .map(Unnormalized::skip_norm_wip)
765 .filter(|clause| #[allow(non_exhaustive_omitted_patterns)] match clause.kind().skip_binder() {
ty::ClauseKind::Trait(_) => true,
_ => false,
}matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(_))),
768 );
769
770 clauses.extend(
786 tcx.clauses_of(trait_def_id)
787 .instantiate_identity(tcx)
788 .clauses
789 .into_iter()
790 .map(Unnormalized::skip_norm_wip)
791 .filter_map(|clause| -> Option<ty::Clause<'tcx>> {
792 clause
793 .as_projection_clause()
794 .filter(|proj| {
798 proj.skip_binder().projection_term.args.iter().any(|arg| {
799 arg.as_type().is_some_and(|arg| arg.contains(tcx.types.self_param))
800 })
801 })
802 .map(|proj| {
803 proj.map_bound(|proj| {
804 EarlyBinder::bind(tcx, proj).instantiate(tcx, args).skip_norm_wip()
805 })
806 .upcast(tcx)
807 })
808 }),
809 );
810
811 let meta_sized_predicate = {
812 let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, DUMMY_SP);
813 ty::TraitRef::new(tcx, meta_sized_did, [unsized_self_ty])
814 };
815 clauses.push(meta_sized_predicate.upcast(tcx));
816
817 normalize_param_env_or_error(
818 tcx,
819 ty::ParamEnv::new(tcx, clauses),
820 ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
821 )
822 };
823
824 let obligation = {
826 let predicate =
827 ty::TraitRef::new(tcx, dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]);
828
829 Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
830 };
831
832 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
833 infcx.predicate_must_hold_modulo_regions(&obligation)
835}
836
837#[derive(#[automatically_derived]impl ::core::marker::Copy for AllowSelfProjections { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
for AllowSelfProjections {
}
#[automatically_derived]impl ::core::clone::Clone for AllowSelfProjections {
#[inline]
#[rustc_trivial_field_reads]
fn clone(&self) -> Self { *self }
}Clone)]
838enum AllowSelfProjections {
839 Yes,
840 No,
841}
842
843fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
885 tcx: TyCtxt<'tcx>,
886 trait_def_id: DefId,
887 value: T,
888 allow_self_projections: AllowSelfProjections,
889) -> bool {
890 value
891 .visit_with(&mut IllegalSelfTypeVisitor {
892 tcx,
893 trait_def_id,
894 supertraits: None,
895 allow_self_projections,
896 })
897 .is_break()
898}
899
900struct IllegalSelfTypeVisitor<'tcx> {
901 tcx: TyCtxt<'tcx>,
902 trait_def_id: DefId,
903 supertraits: Option<Vec<ty::TraitRef<'tcx>>>,
904 allow_self_projections: AllowSelfProjections,
905}
906
907impl<'tcx> IllegalSelfTypeVisitor<'tcx> {
908 fn is_supertrait_of_current_trait(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
909 let supertraits = self.supertraits.get_or_insert_with(|| {
911 util::supertraits(
912 self.tcx,
913 ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id)),
914 )
915 .map(|trait_ref| {
916 self.tcx.erase_and_anonymize_regions(
917 self.tcx.instantiate_bound_regions_with_erased(trait_ref),
918 )
919 })
920 .collect()
921 });
922
923 let trait_ref = trait_ref
929 .fold_with(&mut EraseEscapingBoundRegions { tcx: self.tcx, binder: ty::INNERMOST });
930 supertraits.contains(&trait_ref)
931 }
932}
933
934impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> {
935 type Result = ControlFlow<()>;
936
937 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
938 match ty.kind() {
939 ty::Param(_) => {
940 if ty == self.tcx.types.self_param {
941 ControlFlow::Break(())
942 } else {
943 ControlFlow::Continue(())
944 }
945 }
946 ty::Alias(_, ty::AliasTy { kind: ty::Projection { def_id }, .. })
947 if self.tcx.is_impl_trait_in_trait(*def_id) =>
948 {
949 ControlFlow::Continue(())
951 }
952 ty::Alias(_, proj @ ty::AliasTy { kind: ty::Projection { .. }, .. }) => {
953 match self.allow_self_projections {
954 AllowSelfProjections::Yes => {
955 if self.is_supertrait_of_current_trait(proj.trait_ref(self.tcx)) {
957 ControlFlow::Continue(())
958 } else {
959 ty.super_visit_with(self)
960 }
961 }
962 AllowSelfProjections::No => ty.super_visit_with(self),
963 }
964 }
965 _ => ty.super_visit_with(self),
966 }
967 }
968
969 fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
970 let ct = self.tcx.expand_abstract_consts(ct);
971
972 match ct.kind() {
973 ty::ConstKind::Alias(
974 _,
975 ty::AliasConst { kind: ty::AliasConstKind::Projection { def_id }, args, .. },
976 ) if self.tcx.features().gca_min_const_items() => {
977 match self.allow_self_projections {
978 AllowSelfProjections::Yes => {
979 let trait_def_id = self.tcx.parent(def_id);
980 let trait_ref = ty::TraitRef::from_assoc(self.tcx, trait_def_id, args);
981
982 if self.is_supertrait_of_current_trait(trait_ref) {
984 ControlFlow::Continue(())
985 } else {
986 ct.super_visit_with(self)
987 }
988 }
989 AllowSelfProjections::No => ct.super_visit_with(self),
990 }
991 }
992 _ => ct.super_visit_with(self),
993 }
994 }
995}
996
997struct EraseEscapingBoundRegions<'tcx> {
998 tcx: TyCtxt<'tcx>,
999 binder: ty::DebruijnIndex,
1000}
1001
1002impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEscapingBoundRegions<'tcx> {
1003 fn cx(&self) -> TyCtxt<'tcx> {
1004 self.tcx
1005 }
1006
1007 fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
1008 where
1009 T: TypeFoldable<TyCtxt<'tcx>>,
1010 {
1011 self.binder.shift_in(1);
1012 let result = t.super_fold_with(self);
1013 self.binder.shift_out(1);
1014 result
1015 }
1016
1017 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1018 if let ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) = r.kind()
1019 && debruijn < self.binder
1020 {
1021 r
1022 } else {
1023 self.tcx.lifetimes.re_erased
1024 }
1025 }
1026}
1027
1028fn contains_illegal_impl_trait_in_trait<'tcx>(
1029 tcx: TyCtxt<'tcx>,
1030 fn_def_id: DefId,
1031 ty: ty::Binder<'tcx, Ty<'tcx>>,
1032) -> Option<MethodViolation> {
1033 let ty = tcx.liberate_late_bound_regions(fn_def_id, ty);
1034
1035 if tcx.asyncness(fn_def_id).is_async() {
1036 Some(MethodViolation::AsyncFn)
1038 } else {
1039 ty.visit_with(&mut IllegalRpititVisitor { tcx, allowed: None }).break_value()
1040 }
1041}
1042
1043struct IllegalRpititVisitor<'tcx> {
1044 tcx: TyCtxt<'tcx>,
1045 allowed: Option<ty::AliasTy<'tcx>>,
1046}
1047
1048impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalRpititVisitor<'tcx> {
1049 type Result = ControlFlow<MethodViolation>;
1050
1051 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
1052 if let ty::Alias(_, proj @ ty::AliasTy { kind: ty::Projection { def_id }, .. }) = *ty.kind()
1053 && Some(proj) != self.allowed
1054 && self.tcx.is_impl_trait_in_trait(def_id)
1055 {
1056 ControlFlow::Break(MethodViolation::ReferencesImplTraitInTrait(
1057 self.tcx.def_span(def_id),
1058 ))
1059 } else {
1060 ty.super_visit_with(self)
1061 }
1062 }
1063}
1064
1065pub(crate) fn provide(providers: &mut Providers) {
1066 *providers = Providers {
1067 dyn_compatibility_violations,
1068 is_dyn_compatible,
1069 generics_require_sized_self,
1070 ..*providers
1071 };
1072}