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::{self as ty, IsSuggestable, Ty, TyCtxt};
12use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym};
13use rustc_trait_selection::traits;
14use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
15use smallvec::SmallVec;
16use tracing::{debug, instrument};
17
18use super::errors::GenericsArgsErrExtend;
19use crate::bounds::Bounds;
20use crate::errors;
21use crate::hir_ty_lowering::{
22 AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
23};
24
25impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
26 pub(crate) fn add_sized_bound(
30 &self,
31 bounds: &mut Bounds<'tcx>,
32 self_ty: Ty<'tcx>,
33 hir_bounds: &'tcx [hir::GenericBound<'tcx>],
34 self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
35 span: Span,
36 ) {
37 let tcx = self.tcx();
38 let sized_def_id = tcx.lang_items().sized_trait();
39 let mut seen_negative_sized_bound = false;
40 let mut seen_positive_sized_bound = false;
41
42 let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
44 let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| {
45 for hir_bound in hir_bounds {
46 let hir::GenericBound::Trait(ptr) = hir_bound else {
47 continue;
48 };
49 match ptr.modifiers.polarity {
50 hir::BoundPolarity::Maybe(_) => unbounds.push(ptr),
51 hir::BoundPolarity::Negative(_) => {
52 if let Some(sized_def_id) = sized_def_id
53 && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
54 {
55 seen_negative_sized_bound = true;
56 }
57 }
58 hir::BoundPolarity::Positive => {
59 if let Some(sized_def_id) = sized_def_id
60 && ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
61 {
62 seen_positive_sized_bound = true;
63 }
64 }
65 }
66 }
67 };
68 search_bounds(hir_bounds);
69 if let Some((self_ty, where_clause)) = self_ty_where_predicates {
70 for clause in where_clause {
71 if let hir::WherePredicateKind::BoundPredicate(pred) = clause.kind
72 && pred.is_param_bound(self_ty.to_def_id())
73 {
74 search_bounds(pred.bounds);
75 }
76 }
77 }
78
79 let mut unique_bounds = FxIndexSet::default();
80 let mut seen_repeat = false;
81 for unbound in &unbounds {
82 if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
83 seen_repeat |= !unique_bounds.insert(unbound_def_id);
84 }
85 }
86 if unbounds.len() > 1 {
87 let err = errors::MultipleRelaxedDefaultBounds {
88 spans: unbounds.iter().map(|ptr| ptr.span).collect(),
89 };
90 if seen_repeat {
91 self.dcx().emit_err(err);
92 } else if !tcx.features().more_maybe_bounds() {
93 self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit();
94 };
95 }
96
97 let mut seen_sized_unbound = false;
98 for unbound in unbounds {
99 if let Some(sized_def_id) = sized_def_id
100 && unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
101 {
102 seen_sized_unbound = true;
103 continue;
104 }
105 self.dcx().span_err(
107 unbound.span,
108 "relaxing a default bound only does something for `?Sized`; \
109 all other traits are not bound by default",
110 );
111 }
112
113 if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {
114 } else if sized_def_id.is_some() {
117 bounds.push_sized(tcx, self_ty, span);
120 }
121 }
122
123 #[instrument(level = "debug", skip(self, hir_bounds, bounds))]
145 pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<'tcx>>>(
146 &self,
147 param_ty: Ty<'tcx>,
148 hir_bounds: I,
149 bounds: &mut Bounds<'tcx>,
150 bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
151 predicate_filter: PredicateFilter,
152 ) where
153 'tcx: 'hir,
154 {
155 for hir_bound in hir_bounds {
156 if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
159 if let Some(trait_ref) = hir_bound.trait_ref()
160 && let Some(trait_did) = trait_ref.trait_def_id()
161 && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
162 {
163 } else {
165 continue;
166 }
167 }
168
169 match hir_bound {
170 hir::GenericBound::Trait(poly_trait_ref) => {
171 let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
172 let _ = self.lower_poly_trait_ref(
173 &poly_trait_ref.trait_ref,
174 poly_trait_ref.span,
175 constness,
176 polarity,
177 param_ty,
178 bounds,
179 predicate_filter,
180 );
181 }
182 hir::GenericBound::Outlives(lifetime) => {
183 if matches!(
185 predicate_filter,
186 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst
187 ) {
188 continue;
189 }
190
191 let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
192 bounds.push_region_bound(
193 self.tcx(),
194 ty::Binder::bind_with_vars(
195 ty::OutlivesPredicate(param_ty, region),
196 bound_vars,
197 ),
198 lifetime.ident.span,
199 );
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 Bounds<'tcx>,
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 bounds.push_projection_bound(
393 tcx,
394 projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
395 projection_term,
396 term,
397 }),
398 constraint.span,
399 );
400 }
401 PredicateFilter::SelfTraitThatDefines(_) => {}
403 PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
405 }
406 }
407 hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
410 match predicate_filter {
411 PredicateFilter::All
412 | PredicateFilter::SelfAndAssociatedTypeBounds
413 | PredicateFilter::ConstIfConst => {
414 let projection_ty = projection_term
415 .map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
416 let param_ty =
419 Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder());
420 self.lower_bounds(
421 param_ty,
422 hir_bounds,
423 bounds,
424 projection_ty.bound_vars(),
425 predicate_filter,
426 );
427 }
428 PredicateFilter::SelfOnly
429 | PredicateFilter::SelfTraitThatDefines(_)
430 | PredicateFilter::SelfConstIfConst => {}
431 }
432 }
433 }
434 Ok(())
435 }
436
437 pub fn lower_ty_maybe_return_type_notation(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
440 let hir::TyKind::Path(qpath) = hir_ty.kind else {
441 return self.lower_ty(hir_ty);
442 };
443
444 let tcx = self.tcx();
445 match qpath {
446 hir::QPath::Resolved(opt_self_ty, path)
447 if let [mod_segments @ .., trait_segment, item_segment] = &path.segments[..]
448 && item_segment.args.is_some_and(|args| {
449 matches!(
450 args.parenthesized,
451 hir::GenericArgsParentheses::ReturnTypeNotation
452 )
453 }) =>
454 {
455 let _ =
457 self.prohibit_generic_args(mod_segments.iter(), GenericsArgsErrExtend::None);
458
459 let item_def_id = match path.res {
460 Res::Def(DefKind::AssocFn, item_def_id) => item_def_id,
461 Res::Err => {
462 return Ty::new_error_with_message(
463 tcx,
464 hir_ty.span,
465 "failed to resolve RTN",
466 );
467 }
468 _ => bug!("only expected method resolution for fully qualified RTN"),
469 };
470 let trait_def_id = tcx.parent(item_def_id);
471
472 let Some(self_ty) = opt_self_ty else {
474 return self.error_missing_qpath_self_ty(
475 trait_def_id,
476 hir_ty.span,
477 item_segment,
478 );
479 };
480 let self_ty = self.lower_ty(self_ty);
481
482 let trait_ref = self.lower_mono_trait_ref(
483 hir_ty.span,
484 trait_def_id,
485 self_ty,
486 trait_segment,
487 false,
488 );
489
490 let candidate =
503 ty::Binder::bind_with_vars(trait_ref, tcx.late_bound_vars(item_segment.hir_id));
504
505 match self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span) {
506 Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
507 Err(guar) => Ty::new_error(tcx, guar),
508 }
509 }
510 hir::QPath::TypeRelative(qself, item_segment)
511 if item_segment.args.is_some_and(|args| {
512 matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
513 }) =>
514 {
515 match self
516 .resolve_type_relative_return_type_notation(
517 qself,
518 item_segment,
519 hir_ty.hir_id,
520 hir_ty.span,
521 )
522 .and_then(|(candidate, item_def_id)| {
523 self.lower_return_type_notation_ty(candidate, item_def_id, hir_ty.span)
524 }) {
525 Ok(ty) => Ty::new_alias(tcx, ty::Projection, ty),
526 Err(guar) => Ty::new_error(tcx, guar),
527 }
528 }
529 _ => self.lower_ty(hir_ty),
530 }
531 }
532
533 fn resolve_type_relative_return_type_notation(
536 &self,
537 qself: &'tcx hir::Ty<'tcx>,
538 item_segment: &'tcx hir::PathSegment<'tcx>,
539 qpath_hir_id: HirId,
540 span: Span,
541 ) -> Result<(ty::PolyTraitRef<'tcx>, DefId), ErrorGuaranteed> {
542 let tcx = self.tcx();
543 let qself_ty = self.lower_ty(qself);
544 let assoc_ident = item_segment.ident;
545 let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
546 path.res
547 } else {
548 Res::Err
549 };
550
551 let bound = match (qself_ty.kind(), qself_res) {
552 (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
553 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
556 self.dcx().span_bug(span, "expected cycle error");
558 };
559
560 self.probe_single_bound_for_assoc_item(
561 || {
562 traits::supertraits(
563 tcx,
564 ty::Binder::dummy(trait_ref.instantiate_identity()),
565 )
566 },
567 AssocItemQSelf::SelfTyAlias,
568 ty::AssocKind::Fn,
569 assoc_ident,
570 span,
571 None,
572 )?
573 }
574 (
575 &ty::Param(_),
576 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
577 ) => self.probe_single_ty_param_bound_for_assoc_item(
578 param_did.expect_local(),
579 qself.span,
580 ty::AssocKind::Fn,
581 assoc_ident,
582 span,
583 )?,
584 _ => {
585 if let Err(reported) = qself_ty.error_reported() {
586 return Err(reported);
587 } else {
588 let err = struct_span_code_err!(
590 self.dcx(),
591 span,
592 E0223,
593 "ambiguous associated function"
594 );
595 return Err(err.emit());
596 }
597 }
598 };
599
600 if bound.has_bound_vars() {
607 return Err(self.tcx().dcx().emit_err(
608 errors::AssociatedItemTraitUninferredGenericParams {
609 span,
610 inferred_sugg: Some(span.with_hi(item_segment.ident.span.lo())),
611 bound: format!("{}::", tcx.anonymize_bound_vars(bound).skip_binder(),),
612 mpart_sugg: None,
613 what: "function",
614 },
615 ));
616 }
617
618 let trait_def_id = bound.def_id();
619 let assoc_ty = self
620 .probe_assoc_item(assoc_ident, ty::AssocKind::Fn, qpath_hir_id, span, trait_def_id)
621 .expect("failed to find associated type");
622
623 Ok((bound, assoc_ty.def_id))
624 }
625
626 fn lower_return_type_notation_ty(
631 &self,
632 candidate: ty::PolyTraitRef<'tcx>,
633 item_def_id: DefId,
634 path_span: Span,
635 ) -> Result<ty::AliasTy<'tcx>, ErrorGuaranteed> {
636 let tcx = self.tcx();
637 let mut emitted_bad_param_err = None;
638 let mut num_bound_vars = candidate.bound_vars().len();
641 let args = candidate.skip_binder().args.extend_to(tcx, item_def_id, |param, _| {
642 let arg = match param.kind {
643 ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
644 tcx,
645 ty::INNERMOST,
646 ty::BoundRegion {
647 var: ty::BoundVar::from_usize(num_bound_vars),
648 kind: ty::BoundRegionKind::Named(param.def_id, param.name),
649 },
650 )
651 .into(),
652 ty::GenericParamDefKind::Type { .. } => {
653 let guar = *emitted_bad_param_err.get_or_insert_with(|| {
654 self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Type {
655 span: path_span,
656 param_span: tcx.def_span(param.def_id),
657 })
658 });
659 Ty::new_error(tcx, guar).into()
660 }
661 ty::GenericParamDefKind::Const { .. } => {
662 let guar = *emitted_bad_param_err.get_or_insert_with(|| {
663 self.dcx().emit_err(crate::errors::ReturnTypeNotationIllegalParam::Const {
664 span: path_span,
665 param_span: tcx.def_span(param.def_id),
666 })
667 });
668 ty::Const::new_error(tcx, guar).into()
669 }
670 };
671 num_bound_vars += 1;
672 arg
673 });
674
675 let output = tcx.fn_sig(item_def_id).skip_binder().output();
678 let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
679 && tcx.is_impl_trait_in_trait(alias_ty.def_id)
680 {
681 alias_ty
682 } else {
683 return Err(self.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
684 span: path_span,
685 ty: tcx.liberate_late_bound_regions(item_def_id, output),
686 fn_span: tcx.hir().span_if_local(item_def_id),
687 note: (),
688 }));
689 };
690
691 let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
696 Ok(ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args))
697 }
698}
699
700fn check_assoc_const_binding_type<'tcx>(
712 cx: &dyn HirTyLowerer<'tcx>,
713 assoc_const: Ident,
714 ty: ty::Binder<'tcx, Ty<'tcx>>,
715 hir_id: hir::HirId,
716) -> Ty<'tcx> {
717 let ty = ty.skip_binder();
724 if !ty.has_param() && !ty.has_escaping_bound_vars() {
725 return ty;
726 }
727
728 let mut collector = GenericParamAndBoundVarCollector {
729 cx,
730 params: Default::default(),
731 vars: Default::default(),
732 depth: ty::INNERMOST,
733 };
734 let mut guar = ty.visit_with(&mut collector).break_value();
735
736 let tcx = cx.tcx();
737 let ty_note = ty
738 .make_suggestable(tcx, false, None)
739 .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty });
740
741 let enclosing_item_owner_id = tcx
742 .hir()
743 .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}