1use std::ops::ControlFlow;
2
3use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
4use rustc_errors::codes::*;
5use rustc_errors::struct_span_code_err;
6use rustc_hir as hir;
7use rustc_hir::HirId;
8use rustc_hir::def::{DefKind, Res};
9use rustc_hir::def_id::{DefId, LocalDefId};
10use rustc_middle::bug;
11use rustc_middle::ty::{
12 self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
13 TypeVisitor, Upcast,
14};
15use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
16use rustc_trait_selection::traits;
17use smallvec::SmallVec;
18use tracing::{debug, instrument};
19
20use super::errors::GenericsArgsErrExtend;
21use crate::errors;
22use crate::hir_ty_lowering::{
23 AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
24};
25
26impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
27 pub(crate) fn add_sized_bound(
31 &self,
32 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
33 self_ty: Ty<'tcx>,
34 hir_bounds: &'tcx [hir::GenericBound<'tcx>],
35 self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
36 span: Span,
37 ) {
38 let tcx = self.tcx();
39 let sized_def_id = tcx.lang_items().sized_trait();
40 let mut seen_negative_sized_bound = false;
41 let mut seen_positive_sized_bound = false;
42
43 let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
45 let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
46 for hir_bound in hir_bounds {
47 let hir::GenericBound::Trait(ptr) = hir_bound else {
48 continue;
49 };
50 match ptr.modifiers.polarity {
51 hir::BoundPolarity::Maybe(_) => unbounds.push(ptr),
52 hir::BoundPolarity::Negative(_) => {
53 if let Some(sized_def_id) = sized_def_id
54 && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
55 {
56 seen_negative_sized_bound = true;
57 }
58 }
59 hir::BoundPolarity::Positive => {
60 if let Some(sized_def_id) = sized_def_id
61 && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
62 {
63 seen_positive_sized_bound = true;
64 }
65 }
66 }
67 }
68 };
69 search_bounds(hir_bounds);
70 if let Some((self_ty, where_clause)) = self_ty_where_predicates {
71 for clause in where_clause {
72 if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
73 && pred.is_param_bound(self_ty.to_def_id())
74 {
75 search_bounds(pred.bounds);
76 }
77 }
78 }
79
80 let mut unique_bounds = FxIndexSet::default();
81 let mut seen_repeat = false;
82 for unbound in &unbounds {
83 if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
84 seen_repeat |= !unique_bounds.insert(unbound_def_id);
85 }
86 }
87 if unbounds.len() > 1 {
88 let err = errors::MultipleRelaxedDefaultBounds {
89 spans: unbounds.iter().map(|ptr| ptr.span).collect(),
90 };
91 if seen_repeat {
92 self.dcx().emit_err(err);
93 } else if !tcx.features().more_maybe_bounds() {
94 self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit();
95 };
96 }
97
98 let mut seen_sized_unbound = false;
99 for unbound in unbounds {
100 if let Some(sized_def_id) = sized_def_id
101 && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
102 {
103 seen_sized_unbound = true;
104 continue;
105 }
106 self.dcx().span_err(
108 unbound.span,
109 "relaxing a default bound only does something for `?Sized`; \
110 all other traits are not bound by default",
111 );
112 }
113
114 if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {
115 } else if let Some(sized_def_id) = sized_def_id {
118 let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]);
121 bounds.insert(0, (trait_ref.upcast(tcx), span));
123 }
124 }
125
126 #[instrument(level = "debug", skip(self, hir_bounds, bounds))]
148 pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<'tcx>>>(
149 &self,
150 param_ty: Ty<'tcx>,
151 hir_bounds: I,
152 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
153 bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
154 predicate_filter: PredicateFilter,
155 ) where
156 'tcx: 'hir,
157 {
158 for hir_bound in hir_bounds {
159 if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
162 if let Some(trait_ref) = hir_bound.trait_ref()
163 && let Some(trait_did) = trait_ref.trait_def_id()
164 && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
165 {
166 } else {
168 continue;
169 }
170 }
171
172 match hir_bound {
173 hir::GenericBound::Trait(poly_trait_ref) => {
174 let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
175 let _ = self.lower_poly_trait_ref(
176 &poly_trait_ref.trait_ref,
177 poly_trait_ref.span,
178 constness,
179 polarity,
180 param_ty,
181 bounds,
182 predicate_filter,
183 );
184 }
185 hir::GenericBound::Outlives(lifetime) => {
186 if matches!(
188 predicate_filter,
189 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst
190 ) {
191 continue;
192 }
193
194 let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
195 let bound = ty::Binder::bind_with_vars(
196 ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region)),
197 bound_vars,
198 );
199 bounds.push((bound.upcast(self.tcx()), lifetime.ident.span));
200 }
201 hir::GenericBound::Use(..) => {
202 }
204 }
205 }
206 }
207
208 #[instrument(level = "debug", skip(self, bounds, duplicates, path_span))]
217 pub(super) fn lower_assoc_item_constraint(
218 &self,
219 hir_ref_id: hir::HirId,
220 trait_ref: ty::PolyTraitRef<'tcx>,
221 constraint: &hir::AssocItemConstraint<'tcx>,
222 bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
223 duplicates: &mut FxIndexMap<DefId, Span>,
224 path_span: Span,
225 predicate_filter: PredicateFilter,
226 ) -> Result<(), ErrorGuaranteed> {
227 let tcx = self.tcx();
228
229 let assoc_kind = if constraint.gen_args.parenthesized
230 == hir::GenericArgsParentheses::ReturnTypeNotation
231 {
232 ty::AssocKind::Fn
233 } else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } =
234 constraint.kind
235 {
236 ty::AssocKind::Const
237 } else {
238 ty::AssocKind::Type
239 };
240
241 let candidate = if self.probe_trait_that_defines_assoc_item(
250 trait_ref.def_id(),
251 assoc_kind,
252 constraint.ident,
253 ) {
254 trait_ref
256 } else {
257 self.probe_single_bound_for_assoc_item(
260 || traits::supertraits(tcx, trait_ref),
261 AssocItemQSelf::Trait(trait_ref.def_id()),
262 assoc_kind,
263 constraint.ident,
264 path_span,
265 Some(constraint),
266 )?
267 };
268
269 let assoc_item = self
270 .probe_assoc_item(
271 constraint.ident,
272 assoc_kind,
273 hir_ref_id,
274 constraint.span,
275 candidate.def_id(),
276 )
277 .expect("failed to find associated item");
278
279 duplicates
280 .entry(assoc_item.def_id)
281 .and_modify(|prev_span| {
282 self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
283 span: constraint.span,
284 prev_span: *prev_span,
285 item_name: constraint.ident,
286 def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
287 });
288 })
289 .or_insert(constraint.span);
290
291 let projection_term = if let ty::AssocKind::Fn = assoc_kind {
292 let bound_vars = tcx.late_bound_vars(constraint.hir_id);
293 ty::Binder::bind_with_vars(
294 self.lower_return_type_notation_ty(candidate, assoc_item.def_id, path_span)?.into(),
295 bound_vars,
296 )
297 } else {
298 let alias_term = candidate.map_bound(|trait_ref| {
302 let item_segment = hir::PathSegment {
303 ident: constraint.ident,
304 hir_id: constraint.hir_id,
305 res: Res::Err,
306 args: Some(constraint.gen_args),
307 infer_args: false,
308 };
309
310 let alias_args = self.lower_generic_args_of_assoc_item(
311 path_span,
312 assoc_item.def_id,
313 &item_segment,
314 trait_ref.args,
315 );
316 debug!(?alias_args);
317
318 ty::AliasTerm::new_from_args(tcx, assoc_item.def_id, alias_args)
319 });
320
321 if let Some(const_arg) = constraint.ct() {
323 if let hir::ConstArgKind::Anon(anon_const) = const_arg.kind {
324 let ty = alias_term
325 .map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
326 let ty = check_assoc_const_binding_type(
327 self,
328 constraint.ident,
329 ty,
330 constraint.hir_id,
331 );
332 tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
333 }
334 }
335
336 alias_term
337 };
338
339 match constraint.kind {
340 hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
341 return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
342 span: constraint.span,
343 }));
344 }
345 hir::AssocItemConstraintKind::Equality { term } => {
348 let term = match term {
349 hir::Term::Ty(ty) => self.lower_ty(ty).into(),
350 hir::Term::Const(ct) => self.lower_const_arg(ct, FeedConstTy::No).into(),
351 };
352
353 let late_bound_in_projection_ty =
361 tcx.collect_constrained_late_bound_regions(projection_term);
362 let late_bound_in_term =
363 tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term));
364 debug!(?late_bound_in_projection_ty);
365 debug!(?late_bound_in_term);
366
367 self.validate_late_bound_regions(
373 late_bound_in_projection_ty,
374 late_bound_in_term,
375 |br_name| {
376 struct_span_code_err!(
377 self.dcx(),
378 constraint.span,
379 E0582,
380 "binding for associated type `{}` references {}, \
381 which does not appear in the trait input types",
382 constraint.ident,
383 br_name
384 )
385 },
386 );
387
388 match predicate_filter {
389 PredicateFilter::All
390 | PredicateFilter::SelfOnly
391 | PredicateFilter::SelfAndAssociatedTypeBounds => {
392 let bound = projection_term.map_bound(|projection_term| {
393 ty::ClauseKind::Projection(ty::ProjectionPredicate {
394 projection_term,
395 term,
396 })
397 });
398 bounds.push((bound.upcast(tcx), constraint.span));
399 }
400 PredicateFilter::SelfTraitThatDefines(_) => {}
402 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
404 }
405 }
406 hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
409 match predicate_filter {
410 PredicateFilter::All
411 | PredicateFilter::SelfAndAssociatedTypeBounds
412 | PredicateFilter::ConstIfConst => {
413 let projection_ty = projection_term
414 .map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
415 let param_ty =
418 Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
419 self.lower_bounds(
420 param_ty,
421 hir_bounds,
422 bounds,
423 projection_ty.bound_vars(),
424 predicate_filter,
425 );
426 }
427 PredicateFilter::SelfOnly
428 | PredicateFilter::SelfTraitThatDefines(_)
429 | PredicateFilter::SelfConstIfConst => {}
430 }
431 }
432 }
433 Ok(())
434 }
435
436 pub fn lower_ty_maybe_return_type_notation(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
439 let hir::TyKind::Path(qpath) = hir_ty.kind else {
440 return self.lower_ty(hir_ty);
441 };
442
443 let tcx = self.tcx();
444 match qpath {
445 hir::QPath::Resolved(opt_self_ty, path)
446 if let [mod_segments @ .., trait_segment, item_segment] = &path.segments[..]
447 && item_segment.args.is_some_and(|args| {
448 matches!(
449 args.parenthesized,
450 hir::GenericArgsParentheses::ReturnTypeNotation
451 )
452 }) =>
453 {
454 let _ =
456 self.prohibit_generic_args(mod_segments.iter(), GenericsArgsErrExtend::None);
457
458 let item_def_id = match path.res {
459 Res::Def(DefKind::AssocFn, item_def_id) => item_def_id,
460 Res::Err => {
461 return Ty::new_error_with_message(
462 tcx,
463 hir_ty.span,
464 "failed to resolve RTN",
465 );
466 }
467 _ => bug!("only expected method resolution for fully qualified RTN"),
468 };
469 let trait_def_id = tcx.parent(item_def_id);
470
471 let Some(self_ty) = opt_self_ty else {
473 let guar = self.error_missing_qpath_self_ty(
474 trait_def_id,
475 hir_ty.span,
476 item_segment,
477 ty::AssocKind::Type,
478 );
479 return Ty::new_error(tcx, guar);
480 };
481 let self_ty = self.lower_ty(self_ty);
482
483 let trait_ref = self.lower_mono_trait_ref(
484 hir_ty.span,
485 trait_def_id,
486 self_ty,
487 trait_segment,
488 false,
489 );
490
491 let candidate =
504 ty::Binder::bind_with_vars(trait_ref, tcx.late_bound_vars(item_segment.hir_id));
505
506 match self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span) {
507 Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
508 Err(guar) => Ty::new_error(tcx, guar),
509 }
510 }
511 hir::QPath::TypeRelative(qself, item_segment)
512 if item_segment.args.is_some_and(|args| {
513 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
514 }) =>
515 {
516 match self
517 .resolve_type_relative_return_type_notation(
518 qself,
519 item_segment,
520 hir_ty.hir_id,
521 hir_ty.span,
522 )
523 .and_then(|(candidate, item_def_id)| {
524 self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span)
525 }) {
526 Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
527 Err(guar) => Ty::new_error(tcx, guar),
528 }
529 }
530 _ => self.lower_ty(hir_ty),
531 }
532 }
533
534 fn resolve_type_relative_return_type_notation(
537 &self,
538 qself: &'tcx hir::Ty<'tcx>,
539 item_segment: &'tcx hir::PathSegment<'tcx>,
540 qpath_hir_id: HirId,
541 span: Span,
542 ) -> Result<(ty::PolyTraitRef<'tcx>, DefId), ErrorGuaranteed> {
543 let tcx = self.tcx();
544 let qself_ty = self.lower_ty(qself);
545 let assoc_ident = item_segment.ident;
546 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
547 path.res
548 } else {
549 Res::Err
550 };
551
552 let bound = match (qself_ty.kind(), qself_res) {
553 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
554 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
557 self.dcx().span_bug(span, "expected cycle error");
559 };
560
561 self.probe_single_bound_for_assoc_item(
562 || {
563 traits::supertraits(
564 tcx,
565 ty::Binder::dummy(trait_ref.instantiate_identity()),
566 )
567 },
568 AssocItemQSelf::SelfTyAlias,
569 ty::AssocKind::Fn,
570 assoc_ident,
571 span,
572 None,
573 )?
574 }
575 (
576 &ty::Param(_),
577 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
578 ) => self.probe_single_ty_param_bound_for_assoc_item(
579 param_did.expect_local(),
580 qself.span,
581 ty::AssocKind::Fn,
582 assoc_ident,
583 span,
584 )?,
585 _ => {
586 if let Err(reported) = qself_ty.error_reported() {
587 return Err(reported);
588 } else {
589 let err = struct_span_code_err!(
591 self.dcx(),
592 span,
593 E0223,
594 "ambiguous associated function"
595 );
596 return Err(err.emit());
597 }
598 }
599 };
600
601 if bound.has_bound_vars() {
608 return Err(self.tcx().dcx().emit_err(
609 errors::AssociatedItemTraitUninferredGenericParams {
610 span,
611 inferred_sugg: Some(span.with_hi(item_segment.ident.span.lo())),
612 bound: format!("{}::", tcx.anonymize_bound_vars(bound).skip_binder(),),
613 mpart_sugg: None,
614 what: "function",
615 },
616 ));
617 }
618
619 let trait_def_id = bound.def_id();
620 let assoc_ty = self
621 .probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id)
622 .expect("failed to find associated type");
623
624 Ok((bound, assoc_ty.def_id))
625 }
626
627 fn lower_return_type_notation_ty(
632 &self,
633 candidate: ty::PolyTraitRef<'tcx>,
634 item_def_id: DefId,
635 path_span: Span,
636 ) -> Result<ty::AliasTy<'tcx>, ErrorGuaranteed> {
637 let tcx = self.tcx();
638 let mut emitted_bad_param_err = None;
639 let mut num_bound_vars = candidate.bound_vars().len();
642 let args = candidate.skip_binder().args.extend_to(tcx, item_def_id, |param, _| {
643 let arg = match param.kind {
644 ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
645 tcx,
646 ty::INNERMOST,
647 ty::BoundRegion {
648 var: ty::BoundVar::from_usize(num_bound_vars),
649 kind: ty::BoundRegionKind::Named(param.def_id, param.name),
650 },
651 )
652 .into(),
653 ty::GenericParamDefKind::Type { .. } => {
654 let guar = *emitted_bad_param_err.get_or_insert_with(|| {
655 self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Type {
656 span: path_span,
657 param_span: tcx.def_span(param.def_id),
658 })
659 });
660 Ty::new_error(tcx, guar).into()
661 }
662 ty::GenericParamDefKind::Const { .. } => {
663 let guar = *emitted_bad_param_err.get_or_insert_with(|| {
664 self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Const {
665 span: path_span,
666 param_span: tcx.def_span(param.def_id),
667 })
668 });
669 ty::Const::new_error(tcx, guar).into()
670 }
671 };
672 num_bound_vars += 1;
673 arg
674 });
675
676 let output = tcx.fn_sig(item_def_id).skip_binder().output();
679 let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
680 && tcx.is_impl_trait_in_trait(alias_ty.def_id)
681 {
682 alias_ty
683 } else {
684 return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
685 span: path_span,
686 ty: tcx.liberate_late_bound_regions(item_def_id, output),
687 fn_span: tcx.hir().span_if_local(item_def_id),
688 note: (),
689 }));
690 };
691
692 let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
697 Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args))
698 }
699}
700
701fn check_assoc_const_binding_type<'tcx>(
713 cx: &dyn HirTyLowerer<'tcx>,
714 assoc_const: Ident,
715 ty: ty::Binder<'tcx, Ty<'tcx>>,
716 hir_id: hir::HirId,
717) -> Ty<'tcx> {
718 let ty = ty.skip_binder();
725 if !ty.has_param() && !ty.has_escaping_bound_vars() {
726 return ty;
727 }
728
729 let mut collector = GenericParamAndBoundVarCollector {
730 cx,
731 params: Default::default(),
732 vars: Default::default(),
733 depth: ty::INNERMOST,
734 };
735 let mut guar = ty.visit_with(&mut collector).break_value();
736
737 let tcx = cx.tcx();
738 let ty_note = ty
739 .make_suggestable(tcx, false, None)
740 .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty });
741
742 let enclosing_item_owner_id = tcx
743 .hir_parent_owner_iter(hir_id)
744 .find_map(|(owner_id, parent)| parent.generics().map(|_| owner_id))
745 .unwrap();
746 let generics = tcx.generics_of(enclosing_item_owner_id);
747 for index in collector.params {
748 let param = generics.param_at(index as _, tcx);
749 let is_self_param = param.name == kw::SelfUpper;
750 guar.get_or_insert(cx.dcx().emit_err(crate::errors::ParamInTyOfAssocConstBinding {
751 span: assoc_const.span,
752 assoc_const,
753 param_name: param.name,
754 param_def_kind: tcx.def_descr(param.def_id),
755 param_category: if is_self_param {
756 "self"
757 } else if param.kind.is_synthetic() {
758 "synthetic"
759 } else {
760 "normal"
761 },
762 param_defined_here_label:
763 (!is_self_param).then(|| tcx.def_ident_span(param.def_id).unwrap()),
764 ty_note,
765 }));
766 }
767 for (var_def_id, var_name) in collector.vars {
768 guar.get_or_insert(cx.dcx().emit_err(
769 crate::errors::EscapingBoundVarInTyOfAssocConstBinding {
770 span: assoc_const.span,
771 assoc_const,
772 var_name,
773 var_def_kind: tcx.def_descr(var_def_id),
774 var_defined_here_label: tcx.def_ident_span(var_def_id).unwrap(),
775 ty_note,
776 },
777 ));
778 }
779
780 let guar = guar.unwrap_or_else(|| bug!("failed to find gen params or bound vars in ty"));
781 Ty::new_error(tcx, guar)
782}
783
784struct GenericParamAndBoundVarCollector<'a, 'tcx> {
785 cx: &'a dyn HirTyLowerer<'tcx>,
786 params: FxIndexSet<u32>,
787 vars: FxIndexSet<(DefId, Symbol)>,
788 depth: ty::DebruijnIndex,
789}
790
791impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 'tcx> {
792 type Result = ControlFlow<ErrorGuaranteed>;
793
794 fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
795 &mut self,
796 binder: &ty::Binder<'tcx, T>,
797 ) -> Self::Result {
798 self.depth.shift_in(1);
799 let result = binder.super_visit_with(self);
800 self.depth.shift_out(1);
801 result
802 }
803
804 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
805 match ty.kind() {
806 ty::Param(param) => {
807 self.params.insert(param.index);
808 }
809 ty::Bound(db, bt) if *db >= self.depth => {
810 self.vars.insert(match bt.kind {
811 ty::BoundTyKind::Param(def_id, name) => (def_id, name),
812 ty::BoundTyKind::Anon => {
813 let reported = self
814 .cx
815 .dcx()
816 .delayed_bug(format!("unexpected anon bound ty: {:?}", bt.var));
817 return ControlFlow::Break(reported);
818 }
819 });
820 }
821 _ if ty.has_param() || ty.has_bound_vars() => return ty.super_visit_with(self),
822 _ => {}
823 }
824 ControlFlow::Continue(())
825 }
826
827 fn visit_region(&mut self, re: ty::Region<'tcx>) -> Self::Result {
828 match re.kind() {
829 ty::ReEarlyParam(param) => {
830 self.params.insert(param.index);
831 }
832 ty::ReBound(db, br) if db >= self.depth => {
833 self.vars.insert(match br.kind {
834 ty::BoundRegionKind::Named(def_id, name) => (def_id, name),
835 ty::BoundRegionKind::Anon | ty::BoundRegionKind::ClosureEnv => {
836 let guar = self
837 .cx
838 .dcx()
839 .delayed_bug(format!("unexpected bound region kind: {:?}", br.kind));
840 return ControlFlow::Break(guar);
841 }
842 });
843 }
844 _ => {}
845 }
846 ControlFlow::Continue(())
847 }
848
849 fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
850 match ct.kind() {
851 ty::ConstKind::Param(param) => {
852 self.params.insert(param.index);
853 }
854 ty::ConstKind::Bound(db, ty::BoundVar { .. }) if db >= self.depth => {
855 let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
856 return ControlFlow::Break(guar);
857 }
858 _ if ct.has_param() || ct.has_bound_vars() => return ct.super_visit_with(self),
859 _ => {}
860 }
861 ControlFlow::Continue(())
862 }
863}