1use std::assert_matches;
2
3use hir::Node;
4use rustc_data_structures::fx::FxIndexSet;
5use rustc_hir as hir;
6use rustc_hir::def::DefKind;
7use rustc_hir::def_id::{DefId, LocalDefId};
8use rustc_hir::find_attr;
9use rustc_middle::ty::{
10 self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast,
11};
12use rustc_middle::{bug, span_bug};
13use rustc_span::{DUMMY_SP, Ident, Span};
14use tracing::{debug, instrument, trace};
15
16use super::item_bounds::explicit_item_bounds_with_filter;
17use crate::collect::ItemCtxt;
18use crate::constrained_generic_params as cgp;
19use crate::delegation::inherit_predicates_for_delegation_item;
20use crate::hir_ty_lowering::{
21 HirTyLowerer, ImpliedBoundsContext, OverlappingAsssocItemConstraints, PredicateFilter,
22 RegionInferReason,
23};
24
25#[allow(clippy :: suspicious_else_formatting)]
{
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("predicates_of",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(28u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::tracing_core::field::FieldSet::new(&["def_id"],
::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(&def_id)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[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: ty::GenericPredicates<'_> =
loop {};
return __tracing_attr_fake_return;
}
{
let mut result = tcx.explicit_predicates_of(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_hir_analysis/src/collect/predicates_of.rs:31",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(31u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::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!("predicates_of: explicit_predicates_of({0:?}) = {1:?}",
def_id, result) as &dyn Value))])
});
} else { ; }
};
let inferred_outlives = tcx.inferred_outlives_of(def_id);
if !inferred_outlives.is_empty() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/predicates_of.rs:35",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(35u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::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!("predicates_of: inferred_outlives_of({0:?}) = {1:?}",
def_id, inferred_outlives) as &dyn Value))])
});
} else { ; }
};
let inferred_outlives_iter =
inferred_outlives.iter().map(|(clause, span)|
((*clause).upcast(tcx), *span));
if result.predicates.is_empty() {
result.predicates =
tcx.arena.alloc_from_iter(inferred_outlives_iter);
} else {
result.predicates =
tcx.arena.alloc_from_iter(result.predicates.into_iter().copied().chain(inferred_outlives_iter));
}
}
if tcx.is_trait(def_id) {
let span = DUMMY_SP;
result.predicates =
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((ty::TraitRef::identity(tcx,
def_id).upcast(tcx), span))));
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/predicates_of.rs:76",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(76u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::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!("predicates_of({0:?}) = {1:?}",
def_id, result) as &dyn Value))])
});
} else { ; }
};
result
}
}
}#[instrument(level = "debug", skip(tcx))]
29pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
30 let mut result = tcx.explicit_predicates_of(def_id);
31 debug!("predicates_of: explicit_predicates_of({:?}) = {:?}", def_id, result);
32
33 let inferred_outlives = tcx.inferred_outlives_of(def_id);
34 if !inferred_outlives.is_empty() {
35 debug!("predicates_of: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives,);
36 let inferred_outlives_iter =
37 inferred_outlives.iter().map(|(clause, span)| ((*clause).upcast(tcx), *span));
38 if result.predicates.is_empty() {
39 result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter);
40 } else {
41 result.predicates = tcx.arena.alloc_from_iter(
42 result.predicates.into_iter().copied().chain(inferred_outlives_iter),
43 );
44 }
45 }
46
47 if tcx.is_trait(def_id) {
48 let span = DUMMY_SP;
66
67 result.predicates = tcx.arena.alloc_from_iter(
68 result
69 .predicates
70 .iter()
71 .copied()
72 .chain(std::iter::once((ty::TraitRef::identity(tcx, def_id).upcast(tcx), span))),
73 );
74 }
75
76 debug!("predicates_of({:?}) = {:?}", def_id, result);
77 result
78}
79
80x;#[instrument(level = "trace", skip(tcx), ret)]
83fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::GenericPredicates<'_> {
84 use rustc_hir::*;
85
86 match tcx.opt_rpitit_info(def_id.to_def_id()) {
87 Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => {
88 let mut predicates = Vec::new();
89
90 let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
95 predicates.extend(
96 tcx.explicit_predicates_of(fn_def_id)
97 .instantiate_own(tcx, identity_args)
98 .map(|(c, s)| (c.skip_norm_wip(), s)),
99 );
100
101 compute_bidirectional_outlives_predicates(
106 tcx,
107 &tcx.generics_of(def_id.to_def_id()).own_params
108 [tcx.generics_of(fn_def_id).own_params.len()..],
109 &mut predicates,
110 );
111
112 return ty::GenericPredicates {
113 parent: Some(tcx.local_parent(def_id).to_def_id()),
114 predicates: tcx.arena.alloc_from_iter(predicates),
115 };
116 }
117
118 Some(ImplTraitInTraitData::Impl { fn_def_id }) => {
119 let trait_item_def_id = tcx.trait_item_of(def_id).unwrap();
120 let trait_assoc_predicates = tcx.explicit_predicates_of(trait_item_def_id);
121
122 let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
123 let impl_def_id = tcx.parent(fn_def_id);
124 let impl_trait_ref_args =
125 tcx.impl_trait_ref(impl_def_id).instantiate_identity().skip_norm_wip().args;
126
127 let impl_assoc_args =
128 impl_assoc_identity_args.rebase_onto(tcx, impl_def_id, impl_trait_ref_args);
129
130 let impl_predicates = trait_assoc_predicates
131 .instantiate_own(tcx, impl_assoc_args)
132 .map(|(c, s)| (c.skip_norm_wip(), s));
133
134 return ty::GenericPredicates {
135 parent: Some(impl_def_id),
136 predicates: tcx.arena.alloc_from_iter(impl_predicates),
137 };
138 }
139
140 None => {}
141 }
142
143 let hir_id = tcx.local_def_id_to_hir_id(def_id);
144 let node = tcx.hir_node(hir_id);
145
146 if let Some(sig) = node.fn_sig()
147 && let Some(sig_id) = sig.decl.opt_delegation_sig_id()
148 {
149 return inherit_predicates_for_delegation_item(tcx, def_id, sig_id);
150 }
151
152 let mut is_trait = None;
153 let mut is_default_impl_trait = None;
154
155 let icx = ItemCtxt::new(tcx, def_id);
156
157 const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty();
158
159 let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default();
162
163 let hir_generics = node.generics().unwrap_or(NO_GENERICS);
164 if let Node::Item(item) = node {
165 match item.kind {
166 ItemKind::Impl(impl_) => {
167 if let Some(of_trait) = impl_.of_trait
168 && of_trait.defaultness.is_default()
169 {
170 is_default_impl_trait = Some(ty::Binder::dummy(
171 tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip(),
172 ));
173 }
174 }
175 ItemKind::Trait { bounds: self_bounds, .. }
176 | ItemKind::TraitAlias(_, _, _, self_bounds) => {
177 is_trait = Some((self_bounds, item.span));
178 }
179 _ => {}
180 }
181 };
182
183 let generics = tcx.generics_of(def_id);
184
185 if let Some((self_bounds, span)) = is_trait {
190 let mut bounds = Vec::new();
191 icx.lowerer().lower_bounds(
192 tcx.types.self_param,
193 self_bounds,
194 &mut bounds,
195 ty::List::empty(),
196 PredicateFilter::All,
197 OverlappingAsssocItemConstraints::Allowed,
198 );
199 icx.lowerer().add_implicit_sizedness_bounds(
200 &mut bounds,
201 tcx.types.self_param,
202 self_bounds,
203 &[],
204 ImpliedBoundsContext::TraitDef(def_id),
205 span,
206 );
207 icx.lowerer().add_default_traits(
208 &mut bounds,
209 tcx.types.self_param,
210 self_bounds,
211 &[],
212 ImpliedBoundsContext::TraitDef(def_id),
213 span,
214 );
215 predicates.extend(bounds);
216 }
217
218 if let Some(trait_ref) = is_default_impl_trait {
227 predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id)));
228 }
229
230 for param in hir_generics.params {
234 match param.kind {
235 GenericParamKind::Lifetime { .. } => (),
236 GenericParamKind::Type { .. } => {
237 let param_ty = icx.lowerer().lower_ty_param(param.hir_id);
238 let mut bounds = Vec::new();
239 icx.lowerer().add_implicit_sizedness_bounds(
241 &mut bounds,
242 param_ty,
243 &[],
244 hir_generics.predicates,
245 ImpliedBoundsContext::TyParam(param.def_id),
246 param.span,
247 );
248 icx.lowerer().add_default_traits(
249 &mut bounds,
250 param_ty,
251 &[],
252 hir_generics.predicates,
253 ImpliedBoundsContext::TyParam(param.def_id),
254 param.span,
255 );
256 trace!(?bounds);
257 predicates.extend(bounds);
258 trace!(?predicates);
259 }
260 hir::GenericParamKind::Const { .. } => {
261 let param_def_id = param.def_id.to_def_id();
262 let ct_ty = tcx.type_of(param_def_id).instantiate_identity().skip_norm_wip();
263 let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id);
264 predicates
265 .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
266 }
267 }
268 }
269
270 trace!(?predicates);
271 for predicate in hir_generics.predicates {
273 match predicate.kind {
274 hir::WherePredicateKind::BoundPredicate(bound_pred) => {
275 let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
276 let bound_vars = tcx.late_bound_vars(predicate.hir_id);
277
278 if bound_pred.bounds.is_empty() {
280 if let ty::Param(_) = ty.kind() {
281 } else {
283 let span = bound_pred.bounded_ty.span;
287 let predicate = ty::Binder::bind_with_vars(
288 ty::ClauseKind::WellFormed(ty.into()),
289 bound_vars,
290 );
291 predicates.insert((predicate.upcast(tcx), span));
292 }
293 }
294
295 let mut bounds = Vec::new();
296 icx.lowerer().lower_bounds(
297 ty,
298 bound_pred.bounds,
299 &mut bounds,
300 bound_vars,
301 PredicateFilter::All,
302 OverlappingAsssocItemConstraints::Allowed,
303 );
304 predicates.extend(bounds);
305 }
306
307 hir::WherePredicateKind::RegionPredicate(region_pred) => {
308 let r1 = icx
309 .lowerer()
310 .lower_lifetime(region_pred.lifetime, RegionInferReason::RegionPredicate);
311 predicates.extend(region_pred.bounds.iter().map(|bound| {
312 let (r2, span) = match bound {
313 hir::GenericBound::Outlives(lt) => (
314 icx.lowerer().lower_lifetime(lt, RegionInferReason::RegionPredicate),
315 lt.ident.span,
316 ),
317 bound => {
318 span_bug!(
319 bound.span(),
320 "lifetime param bounds must be outlives, but found {bound:?}"
321 )
322 }
323 };
324 let pred =
325 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)).upcast(tcx);
326 (pred, span)
327 }))
328 }
329 }
330 }
331
332 if tcx.features().generic_const_exprs() {
333 predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates));
334 }
335
336 let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
337 let allow_unstable_feature_attr =
341 find_attr!(attrs, UnstableFeatureBound(i) => i).map(|i| i.as_slice()).unwrap_or_default();
342
343 for (feat_name, span) in allow_unstable_feature_attr {
344 predicates.insert((ty::ClauseKind::UnstableFeature(*feat_name).upcast(tcx), *span));
345 }
346
347 let mut predicates: Vec<_> = predicates.into_iter().collect();
348
349 if let Node::Item(&Item { kind: ItemKind::Impl(impl_), .. }) = node {
355 let self_ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
356 let trait_ref = impl_
357 .of_trait
358 .is_some()
359 .then(|| tcx.impl_trait_ref(def_id).instantiate_identity().skip_norm_wip());
360 cgp::setup_constraining_predicates(
361 tcx,
362 &mut predicates,
363 trait_ref,
364 &mut cgp::parameters_for_impl(tcx, self_ty, trait_ref),
365 );
366 }
367
368 if let Node::OpaqueTy(..) = node {
372 compute_bidirectional_outlives_predicates(tcx, &generics.own_params, &mut predicates);
373 debug!(?predicates);
374 }
375
376 ty::GenericPredicates {
377 parent: generics.parent,
378 predicates: tcx.arena.alloc_from_iter(predicates),
379 }
380}
381
382fn compute_bidirectional_outlives_predicates<'tcx>(
385 tcx: TyCtxt<'tcx>,
386 opaque_own_params: &[ty::GenericParamDef],
387 predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
388) {
389 for param in opaque_own_params {
390 let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
391 if let ty::ReEarlyParam(..) = orig_lifetime.kind() {
392 let dup_lifetime = ty::Region::new_early_param(
393 tcx,
394 ty::EarlyParamRegion { index: param.index, name: param.name },
395 );
396 let span = tcx.def_span(param.def_id);
397 predicates.push((
398 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_lifetime, dup_lifetime))
399 .upcast(tcx),
400 span,
401 ));
402 predicates.push((
403 ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_lifetime, orig_lifetime))
404 .upcast(tcx),
405 span,
406 ));
407 }
408 }
409}
410
411x;#[instrument(level = "debug", skip(tcx, predicates), ret)]
412fn const_evaluatable_predicates_of<'tcx>(
413 tcx: TyCtxt<'tcx>,
414 def_id: LocalDefId,
415 predicates: &FxIndexSet<(ty::Clause<'tcx>, Span)>,
416) -> FxIndexSet<(ty::Clause<'tcx>, Span)> {
417 struct ConstCollector<'tcx> {
418 tcx: TyCtxt<'tcx>,
419 preds: FxIndexSet<(ty::Clause<'tcx>, Span)>,
420 }
421
422 fn is_const_param_default(tcx: TyCtxt<'_>, kind: ty::UnevaluatedConstKind<'_>) -> bool {
423 let ty::UnevaluatedConstKind::Anon { def_id } = kind else { return false };
424 let Some(local) = def_id.as_local() else { return false };
425
426 let hir_id = tcx.local_def_id_to_hir_id(local);
427 let (_, parent_node) = tcx
428 .hir_parent_iter(hir_id)
429 .skip_while(|(_, n)| matches!(n, Node::ConstArg(..)))
430 .next()
431 .unwrap();
432 matches!(
433 parent_node,
434 Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { .. }, .. })
435 )
436 }
437
438 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> {
439 fn visit_const(&mut self, c: ty::Const<'tcx>) {
440 if let ty::ConstKind::Unevaluated(uv) = c.kind() {
441 if is_const_param_default(self.tcx, uv.kind) {
442 return;
450 }
451
452 if uv.kind.is_type_const(self.tcx) {
454 return;
455 }
456
457 let span = uv.kind.def_span(self.tcx);
458 self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span));
459 }
460 }
461 }
462
463 let hir_id = tcx.local_def_id_to_hir_id(def_id);
464 let node = tcx.hir_node(hir_id);
465
466 let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
467
468 for (clause, _sp) in predicates {
469 clause.visit_with(&mut collector);
470 }
471
472 if let hir::Node::Item(item) = node
473 && let hir::ItemKind::Impl(impl_) = item.kind
474 {
475 if impl_.of_trait.is_some() {
476 debug!("visit impl trait_ref");
477 let trait_ref = tcx.impl_trait_ref(def_id);
478 trait_ref.instantiate_identity().skip_norm_wip().visit_with(&mut collector);
479 }
480
481 debug!("visit self_ty");
482 let self_ty = tcx.type_of(def_id);
483 self_ty.instantiate_identity().skip_norm_wip().visit_with(&mut collector);
484 }
485
486 if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) {
487 debug!("visit fn sig");
488 let fn_sig = tcx.fn_sig(def_id);
489 let fn_sig = fn_sig.instantiate_identity().skip_norm_wip();
490 debug!(?fn_sig);
491 fn_sig.visit_with(&mut collector);
492 }
493
494 collector.preds
495}
496
497pub(super) fn trait_explicit_predicates_and_bounds(
498 tcx: TyCtxt<'_>,
499 def_id: LocalDefId,
500) -> ty::GenericPredicates<'_> {
501 match (&tcx.def_kind(def_id), &DefKind::Trait) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
502 gather_explicit_predicates_of(tcx, def_id)
503}
504
505pub(super) fn explicit_predicates_of<'tcx>(
506 tcx: TyCtxt<'tcx>,
507 def_id: LocalDefId,
508) -> ty::GenericPredicates<'tcx> {
509 let def_kind = tcx.def_kind(def_id);
510 if let DefKind::Trait = def_kind {
511 let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id);
514 let trait_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
515
516 let is_assoc_item_ty = |ty: Ty<'tcx>| {
517 if let &ty::Alias(ty::AliasTy {
527 kind: ty::Projection { def_id: projection_def_id },
528 args,
529 ..
530 }) = ty.kind()
531 {
532 args == trait_identity_args
533 && !tcx.is_impl_trait_in_trait(projection_def_id)
535 && tcx.parent(projection_def_id) == def_id.to_def_id()
536 } else {
537 false
538 }
539 };
540
541 let predicates: Vec<_> = predicates_and_bounds
542 .predicates
543 .iter()
544 .copied()
545 .filter(|(pred, _)| match pred.kind().skip_binder() {
546 ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()),
547 ty::ClauseKind::Projection(proj) => {
548 !is_assoc_item_ty(proj.projection_term.self_ty())
549 }
550 ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0),
551 _ => true,
552 })
553 .collect();
554 if predicates.len() == predicates_and_bounds.predicates.len() {
555 predicates_and_bounds
556 } else {
557 ty::GenericPredicates {
558 parent: predicates_and_bounds.parent,
559 predicates: tcx.arena.alloc_slice(&predicates),
560 }
561 }
562 } else {
563 if def_kind == DefKind::AnonConst
564 && tcx.features().generic_const_exprs()
565 && let Some(defaulted_param_def_id) =
566 tcx.hir_opt_const_param_default_param_def_id(tcx.local_def_id_to_hir_id(def_id))
567 {
568 let parent_def_id = tcx.local_parent(def_id);
581 let parent_preds = tcx.explicit_predicates_of(parent_def_id);
582
583 let filtered_predicates = parent_preds
587 .predicates
588 .into_iter()
589 .filter(|(pred, _)| {
590 if let ty::ClauseKind::ConstArgHasType(ct, _) = pred.kind().skip_binder() {
591 match ct.kind() {
592 ty::ConstKind::Param(param_const) => {
593 let defaulted_param_idx = tcx
594 .generics_of(parent_def_id)
595 .param_def_id_to_index[&defaulted_param_def_id.to_def_id()];
596 param_const.index < defaulted_param_idx
597 }
598 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("`ConstArgHasType` in `predicates_of`that isn\'t a `Param` const"))bug!(
599 "`ConstArgHasType` in `predicates_of`\
600 that isn't a `Param` const"
601 ),
602 }
603 } else {
604 true
605 }
606 })
607 .cloned();
608 return GenericPredicates {
609 parent: parent_preds.parent,
610 predicates: { tcx.arena.alloc_from_iter(filtered_predicates) },
611 };
612 }
613 gather_explicit_predicates_of(tcx, def_id)
614 }
615}
616
617pub(super) fn explicit_super_predicates_of<'tcx>(
621 tcx: TyCtxt<'tcx>,
622 trait_def_id: LocalDefId,
623) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
624 implied_predicates_with_filter(tcx, trait_def_id.to_def_id(), PredicateFilter::SelfOnly)
625}
626
627pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
628 tcx: TyCtxt<'tcx>,
629 (trait_def_id, assoc_ident): (DefId, Ident),
630) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
631 implied_predicates_with_filter(
632 tcx,
633 trait_def_id,
634 PredicateFilter::SelfTraitThatDefines(assoc_ident),
635 )
636}
637
638pub(super) fn explicit_implied_predicates_of<'tcx>(
639 tcx: TyCtxt<'tcx>,
640 trait_def_id: LocalDefId,
641) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
642 implied_predicates_with_filter(
643 tcx,
644 trait_def_id.to_def_id(),
645 if tcx.is_trait_alias(trait_def_id.to_def_id()) {
646 PredicateFilter::All
647 } else {
648 PredicateFilter::SelfAndAssociatedTypeBounds
649 },
650 )
651}
652
653pub(super) fn implied_predicates_with_filter<'tcx>(
657 tcx: TyCtxt<'tcx>,
658 trait_def_id: DefId,
659 filter: PredicateFilter,
660) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
661 let Some(trait_def_id) = trait_def_id.as_local() else {
662 {
match filter {
PredicateFilter::SelfTraitThatDefines(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"PredicateFilter::SelfTraitThatDefines(_)",
::core::option::Option::None);
}
}
};assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_));
665 return tcx.explicit_super_predicates_of(trait_def_id);
666 };
667
668 let Node::Item(item) = tcx.hir_node_by_def_id(trait_def_id) else {
669 ::rustc_middle::util::bug::bug_fmt(format_args!("trait_def_id {0:?} is not an item",
trait_def_id));bug!("trait_def_id {trait_def_id:?} is not an item");
670 };
671
672 let (generics, superbounds) = match item.kind {
673 hir::ItemKind::Trait { generics, bounds: supertraits, .. } => (generics, supertraits),
674 hir::ItemKind::TraitAlias(_, _, generics, supertraits) => (generics, supertraits),
675 _ => ::rustc_middle::util::bug::span_bug_fmt(item.span,
format_args!("super_predicates invoked on non-trait"))span_bug!(item.span, "super_predicates invoked on non-trait"),
676 };
677
678 let icx = ItemCtxt::new(tcx, trait_def_id);
679
680 let self_param_ty = tcx.types.self_param;
681 let mut bounds = Vec::new();
682 icx.lowerer().lower_bounds(
683 self_param_ty,
684 superbounds,
685 &mut bounds,
686 ty::List::empty(),
687 filter,
688 OverlappingAsssocItemConstraints::Allowed,
689 );
690 match filter {
691 PredicateFilter::All
692 | PredicateFilter::SelfOnly
693 | PredicateFilter::SelfTraitThatDefines(_)
694 | PredicateFilter::SelfAndAssociatedTypeBounds => {
695 icx.lowerer().add_implicit_sizedness_bounds(
696 &mut bounds,
697 self_param_ty,
698 superbounds,
699 &[],
700 ImpliedBoundsContext::TraitDef(trait_def_id),
701 item.span,
702 );
703 icx.lowerer().add_default_traits(
704 &mut bounds,
705 self_param_ty,
706 superbounds,
707 &[],
708 ImpliedBoundsContext::TraitDef(trait_def_id),
709 item.span,
710 );
711 }
712 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
714 }
715
716 let where_bounds_that_match =
717 icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
718
719 let implied_bounds =
721 &*tcx.arena.alloc_from_iter(bounds.into_iter().chain(where_bounds_that_match));
722 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/predicates_of.rs:722",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(722u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::tracing_core::field::FieldSet::new(&["implied_bounds"],
::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(&implied_bounds)
as &dyn Value))])
});
} else { ; }
};debug!(?implied_bounds);
723
724 match filter {
729 PredicateFilter::SelfOnly => {
730 for &(pred, span) in implied_bounds {
731 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/predicates_of.rs:731",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(731u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::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!("superbound: {0:?}",
pred) as &dyn Value))])
});
} else { ; }
};debug!("superbound: {:?}", pred);
732 if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
733 && bound.polarity == ty::PredicatePolarity::Positive
734 {
735 tcx.at(span).explicit_super_predicates_of(bound.def_id());
736 }
737 }
738 }
739 PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
740 for &(pred, span) in implied_bounds {
741 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/collect/predicates_of.rs:741",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(741u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::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!("superbound: {0:?}",
pred) as &dyn Value))])
});
} else { ; }
};debug!("superbound: {:?}", pred);
742 if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
743 && bound.polarity == ty::PredicatePolarity::Positive
744 {
745 tcx.at(span).explicit_implied_predicates_of(bound.def_id());
746 }
747 }
748 }
749 _ => {}
750 }
751
752 assert_only_contains_predicates_from(filter, implied_bounds, tcx.types.self_param);
753
754 ty::EarlyBinder::bind(implied_bounds)
755}
756
757pub(super) fn assert_only_contains_predicates_from<'tcx>(
761 filter: PredicateFilter,
762 bounds: &'tcx [(ty::Clause<'tcx>, Span)],
763 ty: Ty<'tcx>,
764) {
765 if !truecfg!(debug_assertions) {
766 return;
767 }
768
769 match filter {
770 PredicateFilter::SelfOnly => {
771 for (clause, _) in bounds {
772 match clause.kind().skip_binder() {
773 ty::ClauseKind::Trait(trait_predicate) => {
774 match (&trait_predicate.self_ty(), &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
775 trait_predicate.self_ty(),
776 ty,
777 "expected `Self` predicate when computing \
778 `{filter:?}` implied bounds: {clause:?}"
779 );
780 }
781 ty::ClauseKind::Projection(projection_predicate) => {
782 match (&projection_predicate.self_ty(), &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
783 projection_predicate.self_ty(),
784 ty,
785 "expected `Self` predicate when computing \
786 `{filter:?}` implied bounds: {clause:?}"
787 );
788 }
789 ty::ClauseKind::TypeOutlives(outlives_predicate) => {
790 match (&outlives_predicate.0, &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
791 outlives_predicate.0, ty,
792 "expected `Self` predicate when computing \
793 `{filter:?}` implied bounds: {clause:?}"
794 );
795 }
796 ty::ClauseKind::HostEffect(host_effect_predicate) => {
797 match (&host_effect_predicate.self_ty(), &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
798 host_effect_predicate.self_ty(),
799 ty,
800 "expected `Self` predicate when computing \
801 `{filter:?}` implied bounds: {clause:?}"
802 );
803 }
804
805 ty::ClauseKind::RegionOutlives(_)
806 | ty::ClauseKind::ConstArgHasType(_, _)
807 | ty::ClauseKind::WellFormed(_)
808 | ty::ClauseKind::UnstableFeature(_)
809 | ty::ClauseKind::ConstEvaluatable(_) => {
810 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected non-`Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause));bug!(
811 "unexpected non-`Self` predicate when computing \
812 `{filter:?}` implied bounds: {clause:?}"
813 );
814 }
815 }
816 }
817 }
818 PredicateFilter::SelfTraitThatDefines(_) => {
819 for (clause, _) in bounds {
820 match clause.kind().skip_binder() {
821 ty::ClauseKind::Trait(trait_predicate) => {
822 match (&trait_predicate.self_ty(), &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
823 trait_predicate.self_ty(),
824 ty,
825 "expected `Self` predicate when computing \
826 `{filter:?}` implied bounds: {clause:?}"
827 );
828 }
829
830 ty::ClauseKind::Projection(_)
831 | ty::ClauseKind::TypeOutlives(_)
832 | ty::ClauseKind::RegionOutlives(_)
833 | ty::ClauseKind::ConstArgHasType(_, _)
834 | ty::ClauseKind::WellFormed(_)
835 | ty::ClauseKind::ConstEvaluatable(_)
836 | ty::ClauseKind::UnstableFeature(_)
837 | ty::ClauseKind::HostEffect(..) => {
838 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected non-`Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause));bug!(
839 "unexpected non-`Self` predicate when computing \
840 `{filter:?}` implied bounds: {clause:?}"
841 );
842 }
843 }
844 }
845 }
846 PredicateFilter::ConstIfConst => {
847 for (clause, _) in bounds {
848 match clause.kind().skip_binder() {
849 ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
850 trait_ref: _,
851 constness: ty::BoundConstness::Maybe,
852 }) => {}
853 _ => {
854 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected non-`HostEffect` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause));bug!(
855 "unexpected non-`HostEffect` predicate when computing \
856 `{filter:?}` implied bounds: {clause:?}"
857 );
858 }
859 }
860 }
861 }
862 PredicateFilter::SelfConstIfConst => {
863 for (clause, _) in bounds {
864 match clause.kind().skip_binder() {
865 ty::ClauseKind::HostEffect(pred) => {
866 match (&pred.constness, &ty::BoundConstness::Maybe) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `[const]` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
867 pred.constness,
868 ty::BoundConstness::Maybe,
869 "expected `[const]` predicate when computing `{filter:?}` \
870 implied bounds: {clause:?}",
871 );
872 match (&pred.trait_ref.self_ty(), &ty) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("expected `Self` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause)));
}
}
};assert_eq!(
873 pred.trait_ref.self_ty(),
874 ty,
875 "expected `Self` predicate when computing `{filter:?}` \
876 implied bounds: {clause:?}"
877 );
878 }
879 _ => {
880 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected non-`HostEffect` predicate when computing `{0:?}` implied bounds: {1:?}",
filter, clause));bug!(
881 "unexpected non-`HostEffect` predicate when computing \
882 `{filter:?}` implied bounds: {clause:?}"
883 );
884 }
885 }
886 }
887 }
888 PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
889 }
890}
891
892#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("type_param_predicates",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(894u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::tracing_core::field::FieldSet::new(&["item_def_id",
"def_id", "assoc_ident"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(&item_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(&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(&assoc_ident)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[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:
ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> =
loop {};
return __tracing_attr_fake_return;
}
{
match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =>
{
return tcx.type_param_predicates((opaque_def_id.expect_local(),
def_id, assoc_ident));
}
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("should not be lowering bounds on RPITIT in impl")));
}
}
None => {}
}
let param_id = tcx.local_def_id_to_hir_id(def_id);
let param_owner = tcx.hir_ty_param_owner(def_id);
let parent =
if item_def_id == param_owner {
None
} else {
tcx.generics_of(item_def_id).parent.map(|def_id|
def_id.expect_local())
};
let result =
if let Some(parent) = parent {
let icx = ItemCtxt::new(tcx, parent);
icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_ident)
} else { ty::EarlyBinder::bind(&[] as &[_]) };
let mut extend = None;
let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
let hir_node = tcx.hir_node(item_hir_id);
let Some(hir_generics) =
hir_node.generics() else { return result; };
if let Node::Item(item) = hir_node &&
let hir::ItemKind::Trait { .. } = item.kind &&
param_id == item_hir_id {
let identity_trait_ref =
ty::TraitRef::identity(tcx, item_def_id.to_def_id());
extend = Some((identity_trait_ref.upcast(tcx), item.span));
}
let icx = ItemCtxt::new(tcx, item_def_id);
let extra_predicates =
extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(hir_generics,
def_id,
PredicateFilter::SelfTraitThatDefines(assoc_ident)));
let bounds =
&*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates));
let self_ty =
match tcx.def_kind(def_id) {
DefKind::TyParam =>
Ty::new_param(tcx,
tcx.generics_of(item_def_id).param_def_id_to_index(tcx,
def_id.to_def_id()).expect("expected generic param to be owned by item"),
tcx.item_name(def_id.to_def_id())),
DefKind::Trait | DefKind::TraitAlias =>
tcx.types.self_param,
_ =>
::core::panicking::panic("internal error: entered unreachable code"),
};
assert_only_contains_predicates_from(PredicateFilter::SelfTraitThatDefines(assoc_ident),
bounds, self_ty);
ty::EarlyBinder::bind(bounds)
}
}
}#[instrument(level = "trace", skip(tcx))]
895pub(super) fn type_param_predicates<'tcx>(
896 tcx: TyCtxt<'tcx>,
897 (item_def_id, def_id, assoc_ident): (LocalDefId, LocalDefId, Ident),
898) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
899 match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
900 Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
901 return tcx.type_param_predicates((opaque_def_id.expect_local(), def_id, assoc_ident));
902 }
903 Some(ty::ImplTraitInTraitData::Impl { .. }) => {
904 unreachable!("should not be lowering bounds on RPITIT in impl")
905 }
906 None => {}
907 }
908
909 let param_id = tcx.local_def_id_to_hir_id(def_id);
914 let param_owner = tcx.hir_ty_param_owner(def_id);
915
916 let parent = if item_def_id == param_owner {
918 None
920 } else {
921 tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
922 };
923
924 let result = if let Some(parent) = parent {
925 let icx = ItemCtxt::new(tcx, parent);
926 icx.probe_ty_param_bounds(DUMMY_SP, def_id, assoc_ident)
927 } else {
928 ty::EarlyBinder::bind(&[] as &[_])
929 };
930 let mut extend = None;
931
932 let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id);
933
934 let hir_node = tcx.hir_node(item_hir_id);
935 let Some(hir_generics) = hir_node.generics() else {
936 return result;
937 };
938
939 if let Node::Item(item) = hir_node
940 && let hir::ItemKind::Trait { .. } = item.kind
941 && param_id == item_hir_id
943 {
944 let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id.to_def_id());
945 extend = Some((identity_trait_ref.upcast(tcx), item.span));
946 }
947
948 let icx = ItemCtxt::new(tcx, item_def_id);
949 let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(
950 hir_generics,
951 def_id,
952 PredicateFilter::SelfTraitThatDefines(assoc_ident),
953 ));
954
955 let bounds =
956 &*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates));
957
958 let self_ty = match tcx.def_kind(def_id) {
960 DefKind::TyParam => Ty::new_param(
961 tcx,
962 tcx.generics_of(item_def_id)
963 .param_def_id_to_index(tcx, def_id.to_def_id())
964 .expect("expected generic param to be owned by item"),
965 tcx.item_name(def_id.to_def_id()),
966 ),
967 DefKind::Trait | DefKind::TraitAlias => tcx.types.self_param,
968 _ => unreachable!(),
969 };
970 assert_only_contains_predicates_from(
971 PredicateFilter::SelfTraitThatDefines(assoc_ident),
972 bounds,
973 self_ty,
974 );
975
976 ty::EarlyBinder::bind(bounds)
977}
978
979impl<'tcx> ItemCtxt<'tcx> {
980 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("probe_ty_param_bounds_in_generics",
"rustc_hir_analysis::collect::predicates_of",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/collect/predicates_of.rs"),
::tracing_core::__macro_support::Option::Some(985u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::collect::predicates_of"),
::tracing_core::field::FieldSet::new(&["param_def_id",
"filter"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::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(¶m_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(&filter)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[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<(ty::Clause<'tcx>, Span)> =
loop {};
return __tracing_attr_fake_return;
}
{
let mut bounds = Vec::new();
if let PredicateFilter::All = filter {
for param in hir_generics.params {
match param.kind {
hir::GenericParamKind::Type { .. } => {
let param_ty = self.lowerer().lower_ty_param(param.hir_id);
self.lowerer().add_implicit_sizedness_bounds(&mut bounds,
param_ty, &[], hir_generics.predicates,
ImpliedBoundsContext::TyParam(param.def_id), param.span);
self.lowerer().add_default_traits(&mut bounds, param_ty,
&[], hir_generics.predicates,
ImpliedBoundsContext::TyParam(param.def_id), param.span);
}
hir::GenericParamKind::Lifetime { .. } |
hir::GenericParamKind::Const { .. } => {}
}
}
}
for predicate in hir_generics.predicates {
let hir_id = predicate.hir_id;
let hir::WherePredicateKind::BoundPredicate(predicate) =
predicate.kind else { continue; };
match filter {
_ if predicate.is_param_bound(param_def_id.to_def_id()) =>
{}
PredicateFilter::All => {}
PredicateFilter::SelfOnly |
PredicateFilter::SelfTraitThatDefines(_) |
PredicateFilter::SelfConstIfConst |
PredicateFilter::SelfAndAssociatedTypeBounds => continue,
PredicateFilter::ConstIfConst =>
::core::panicking::panic("internal error: entered unreachable code"),
}
let bound_ty =
self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
let bound_vars = self.tcx.late_bound_vars(hir_id);
self.lowerer().lower_bounds(bound_ty, predicate.bounds,
&mut bounds, bound_vars, filter,
OverlappingAsssocItemConstraints::Allowed);
}
bounds
}
}
}#[instrument(level = "trace", skip(self, hir_generics))]
986 fn probe_ty_param_bounds_in_generics(
987 &self,
988 hir_generics: &'tcx hir::Generics<'tcx>,
989 param_def_id: LocalDefId,
990 filter: PredicateFilter,
991 ) -> Vec<(ty::Clause<'tcx>, Span)> {
992 let mut bounds = Vec::new();
993
994 if let PredicateFilter::All = filter {
995 for param in hir_generics.params {
996 match param.kind {
997 hir::GenericParamKind::Type { .. } => {
998 let param_ty = self.lowerer().lower_ty_param(param.hir_id);
999 self.lowerer().add_implicit_sizedness_bounds(
1000 &mut bounds,
1001 param_ty,
1002 &[],
1003 hir_generics.predicates,
1004 ImpliedBoundsContext::TyParam(param.def_id),
1005 param.span,
1006 );
1007 self.lowerer().add_default_traits(
1008 &mut bounds,
1009 param_ty,
1010 &[],
1011 hir_generics.predicates,
1012 ImpliedBoundsContext::TyParam(param.def_id),
1013 param.span,
1014 );
1015 }
1016 hir::GenericParamKind::Lifetime { .. }
1017 | hir::GenericParamKind::Const { .. } => {}
1018 }
1019 }
1020 }
1021
1022 for predicate in hir_generics.predicates {
1023 let hir_id = predicate.hir_id;
1024 let hir::WherePredicateKind::BoundPredicate(predicate) = predicate.kind else {
1025 continue;
1026 };
1027
1028 match filter {
1029 _ if predicate.is_param_bound(param_def_id.to_def_id()) => {
1030 }
1032 PredicateFilter::All => {
1033 }
1035 PredicateFilter::SelfOnly
1036 | PredicateFilter::SelfTraitThatDefines(_)
1037 | PredicateFilter::SelfConstIfConst
1038 | PredicateFilter::SelfAndAssociatedTypeBounds => continue,
1039 PredicateFilter::ConstIfConst => unreachable!(),
1040 }
1041
1042 let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
1043
1044 let bound_vars = self.tcx.late_bound_vars(hir_id);
1045 self.lowerer().lower_bounds(
1046 bound_ty,
1047 predicate.bounds,
1048 &mut bounds,
1049 bound_vars,
1050 filter,
1051 OverlappingAsssocItemConstraints::Allowed,
1052 );
1053 }
1054
1055 bounds
1056 }
1057}
1058
1059pub(super) fn const_conditions<'tcx>(
1060 tcx: TyCtxt<'tcx>,
1061 def_id: LocalDefId,
1062) -> ty::ConstConditions<'tcx> {
1063 if !tcx.is_conditionally_const(def_id) {
1064 ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions invoked for item that is not conditionally const: {0:?}",
def_id));bug!("const_conditions invoked for item that is not conditionally const: {def_id:?}");
1065 }
1066
1067 match tcx.opt_rpitit_info(def_id.to_def_id()) {
1068 Some(
1070 ty::ImplTraitInTraitData::Impl { fn_def_id }
1071 | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
1072 ) => return tcx.const_conditions(fn_def_id),
1073 None => {}
1074 }
1075
1076 let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id)
1077 {
1078 Node::Item(item) => match item.kind {
1079 hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
1080 hir::ItemKind::Fn { generics, .. } => (generics, None, false),
1081 hir::ItemKind::Trait { generics, bounds: supertraits, .. } => {
1082 (generics, Some((Some(item.owner_id.def_id), supertraits)), false)
1083 }
1084 hir::ItemKind::TraitAlias(_, _, generics, supertraits) => {
1085 (generics, Some((None, supertraits)), false)
1086 }
1087 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions called on wrong item: {0:?}",
def_id))bug!("const_conditions called on wrong item: {def_id:?}"),
1088 },
1089 Node::TraitItem(item) => match item.kind {
1094 hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => {
1095 (item.generics, None, true)
1096 }
1097 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions called on wrong item: {0:?}",
def_id))bug!("const_conditions called on wrong item: {def_id:?}"),
1098 },
1099 Node::ImplItem(item) => match item.kind {
1100 hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => {
1101 (item.generics, None, tcx.is_conditionally_const(tcx.local_parent(def_id)))
1102 }
1103 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions called on wrong item: {0:?}",
def_id))bug!("const_conditions called on wrong item: {def_id:?}"),
1104 },
1105 Node::ForeignItem(item) => match item.kind {
1106 hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
1107 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions called on wrong item: {0:?}",
def_id))bug!("const_conditions called on wrong item: {def_id:?}"),
1108 },
1109 Node::OpaqueTy(opaque) => match opaque.origin {
1110 hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent),
1111 hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => {
1112 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1113 }
1114 },
1115 Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
1117 Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_), .. }) => {
1118 (hir::Generics::empty(), None, tcx.is_conditionally_const(tcx.local_parent(def_id)))
1119 }
1120 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("const_conditions called on wrong item: {0:?}",
def_id))bug!("const_conditions called on wrong item: {def_id:?}"),
1121 };
1122
1123 let icx = ItemCtxt::new(tcx, def_id);
1124 let mut bounds = Vec::new();
1125
1126 for pred in generics.predicates {
1127 match pred.kind {
1128 hir::WherePredicateKind::BoundPredicate(bound_pred) => {
1129 let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
1130 let bound_vars = tcx.late_bound_vars(pred.hir_id);
1131 icx.lowerer().lower_bounds(
1132 ty,
1133 bound_pred.bounds.iter(),
1134 &mut bounds,
1135 bound_vars,
1136 PredicateFilter::ConstIfConst,
1137 OverlappingAsssocItemConstraints::Allowed,
1138 );
1139 }
1140 _ => {}
1141 }
1142 }
1143
1144 if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
1145 if let Some(def_id) = def_id {
1146 bounds.push((
1148 ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
1149 .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
1150 DUMMY_SP,
1151 ));
1152 }
1153
1154 icx.lowerer().lower_bounds(
1155 tcx.types.self_param,
1156 supertraits,
1157 &mut bounds,
1158 ty::List::empty(),
1159 PredicateFilter::ConstIfConst,
1160 OverlappingAsssocItemConstraints::Allowed,
1161 );
1162 }
1163
1164 ty::ConstConditions {
1165 parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()),
1166 predicates: tcx.arena.alloc_from_iter(bounds.into_iter().map(|(clause, span)| {
1167 (
1168 clause.kind().map_bound(|clause| match clause {
1169 ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
1170 trait_ref,
1171 constness: ty::BoundConstness::Maybe,
1172 }) => trait_ref,
1173 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("converted {0:?}", clause))bug!("converted {clause:?}"),
1174 }),
1175 span,
1176 )
1177 })),
1178 }
1179}
1180
1181pub(super) fn explicit_implied_const_bounds<'tcx>(
1182 tcx: TyCtxt<'tcx>,
1183 def_id: LocalDefId,
1184) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
1185 if !tcx.is_conditionally_const(def_id) {
1186 ::rustc_middle::util::bug::bug_fmt(format_args!("explicit_implied_const_bounds invoked for item that is not conditionally const: {0:?}",
def_id));bug!(
1187 "explicit_implied_const_bounds invoked for item that is not conditionally const: {def_id:?}"
1188 );
1189 }
1190
1191 let bounds = match tcx.opt_rpitit_info(def_id.to_def_id()) {
1192 Some(ty::ImplTraitInTraitData::Trait { .. }) => {
1195 explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
1196 }
1197 Some(ty::ImplTraitInTraitData::Impl { .. }) => {
1198 ::rustc_middle::util::bug::span_bug_fmt(tcx.def_span(def_id),
format_args!("RPITIT in impl should not have item bounds"))span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
1199 }
1200 None => match tcx.hir_node_by_def_id(def_id) {
1201 Node::Item(hir::Item {
1202 kind: hir::ItemKind::Trait { .. } | hir::ItemKind::TraitAlias(..),
1203 ..
1204 }) => implied_predicates_with_filter(
1205 tcx,
1206 def_id.to_def_id(),
1207 PredicateFilter::SelfConstIfConst,
1208 ),
1209 Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
1210 | Node::OpaqueTy(_) => {
1211 explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
1212 }
1213 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("explicit_implied_const_bounds called on wrong item: {0:?}",
def_id))bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
1214 },
1215 };
1216
1217 bounds.map_bound(|bounds| {
1218 &*tcx.arena.alloc_from_iter(bounds.iter().copied().map(|(clause, span)| {
1219 (
1220 clause.kind().map_bound(|clause| match clause {
1221 ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
1222 trait_ref,
1223 constness: ty::BoundConstness::Maybe,
1224 }) => trait_ref,
1225 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("converted {0:?}", clause))bug!("converted {clause:?}"),
1226 }),
1227 span,
1228 )
1229 }))
1230 })
1231}