@@ -71,22 +71,17 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
7171 }
7272
7373 Node :: TypeBinding ( & TypeBinding { hir_id, ident, .. } ) => {
74- let ty = tcx. type_of_assoc_const_binding ( hir_id) ;
74+ let ty = tcx. type_of_assoc_const_binding ( hir_id) . skip_binder ( ) . skip_binder ( ) ;
7575
7676 // We can't possibly catch this in the resolver, therefore we need to handle it here.
7777 // FIXME(const_generics): Support generic const generics.
78- let Some ( ty) = ty. no_bound_vars ( ) else {
79- let reported = report_overly_generic_assoc_const_binding_type (
80- tcx,
81- ident,
82- ty. skip_binder ( ) . skip_binder ( ) ,
83- hir_id,
84- ) ;
78+ if ty. has_param ( ) || ty. has_escaping_bound_vars ( ) {
79+ let reported =
80+ report_overly_generic_assoc_const_binding_type ( tcx, ident, ty, hir_id) ;
8581 return Ty :: new_error ( tcx, reported) ;
8682 } ;
8783
88- // FIXME(fmease): Reject escaping late-bound vars.
89- return ty. skip_binder ( ) ;
84+ return ty;
9085 }
9186
9287 // This match arm is for when the def_id appears in a GAT whose
@@ -313,8 +308,15 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
313308 ty : Ty < ' tcx > ,
314309 hir_id : HirId ,
315310) -> ErrorGuaranteed {
316- let mut collector = GenericParamCollector { params : Default :: default ( ) } ;
317- ty. visit_with ( & mut collector) ;
311+ let mut collector = GenericParamAndBoundVarCollector {
312+ tcx,
313+ params : Default :: default ( ) ,
314+ vars : Default :: default ( ) ,
315+ depth : ty:: INNERMOST ,
316+ } ;
317+ if let ControlFlow :: Break ( reported) = ty. visit_with ( & mut collector) {
318+ return reported;
319+ }
318320
319321 let mut reported = None ;
320322
@@ -331,40 +333,99 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
331333 param_defined_here_label : tcx. def_ident_span ( param_def. def_id ) . unwrap ( ) ,
332334 } ) ) ;
333335 }
336+ for ( var_def_id, var_name) in collector. vars {
337+ reported. get_or_insert ( tcx. dcx ( ) . emit_err (
338+ crate :: errors:: EscapingBoundVarInTyOfAssocConstBinding {
339+ span : assoc_const. span ,
340+ assoc_const,
341+ var_name,
342+ var_def_kind : tcx. def_descr ( var_def_id) ,
343+ var_defined_here_label : tcx. def_ident_span ( var_def_id) . unwrap ( ) ,
344+ } ,
345+ ) ) ;
346+ }
334347
335- struct GenericParamCollector {
348+ struct GenericParamAndBoundVarCollector < ' tcx > {
349+ tcx : TyCtxt < ' tcx > ,
336350 params : FxIndexSet < ( u32 , Symbol ) > ,
351+ vars : FxIndexSet < ( DefId , Symbol ) > ,
352+ depth : ty:: DebruijnIndex ,
337353 }
338354
339- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamCollector {
340- type BreakTy = !;
355+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamAndBoundVarCollector < ' tcx > {
356+ type BreakTy = ErrorGuaranteed ;
357+
358+ fn visit_binder < T : TypeVisitable < TyCtxt < ' tcx > > > (
359+ & mut self ,
360+ binder : & ty:: Binder < ' tcx , T > ,
361+ ) -> ControlFlow < Self :: BreakTy > {
362+ self . depth . shift_in ( 1 ) ;
363+ let binder = binder. super_visit_with ( self ) ;
364+ self . depth . shift_out ( 1 ) ;
365+ binder
366+ }
341367
342368 fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
343- if let ty:: Param ( param) = ty. kind ( ) {
344- self . params . insert ( ( param. index , param. name ) ) ;
345- return ControlFlow :: Continue ( ( ) ) ;
369+ match ty. kind ( ) {
370+ ty:: Param ( param) => {
371+ self . params . insert ( ( param. index , param. name ) ) ;
372+ }
373+ ty:: Bound ( db, bt) if * db >= self . depth => {
374+ self . vars . insert ( match bt. kind {
375+ ty:: BoundTyKind :: Param ( def_id, name) => ( def_id, name) ,
376+ ty:: BoundTyKind :: Anon => {
377+ let reported = self
378+ . tcx
379+ . dcx ( )
380+ . delayed_bug ( format ! ( "unexpected anon bound ty: {:?}" , bt. var) ) ;
381+ return ControlFlow :: Break ( reported) ;
382+ }
383+ } ) ;
384+ }
385+ _ => return ty. super_visit_with ( self ) ,
346386 }
347- ty . super_visit_with ( self )
387+ ControlFlow :: Continue ( ( ) )
348388 }
349389
350390 fn visit_region ( & mut self , re : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
351- if let ty:: ReEarlyParam ( param) = re. kind ( ) {
352- self . params . insert ( ( param. index , param. name ) ) ;
353- return ControlFlow :: Continue ( ( ) ) ;
391+ match re. kind ( ) {
392+ ty:: ReEarlyParam ( param) => {
393+ self . params . insert ( ( param. index , param. name ) ) ;
394+ }
395+ ty:: ReBound ( db, br) if db >= self . depth => {
396+ self . vars . insert ( match br. kind {
397+ ty:: BrNamed ( def_id, name) => ( def_id, name) ,
398+ ty:: BrAnon | ty:: BrEnv => {
399+ let reported = self . tcx . dcx ( ) . delayed_bug ( format ! (
400+ "unexpected bound region kind: {:?}" ,
401+ br. kind
402+ ) ) ;
403+ return ControlFlow :: Break ( reported) ;
404+ }
405+ } ) ;
406+ }
407+ _ => { }
354408 }
355409 ControlFlow :: Continue ( ( ) )
356410 }
357411
358412 fn visit_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
359- if let ty:: ConstKind :: Param ( param) = ct. kind ( ) {
360- self . params . insert ( ( param. index , param. name ) ) ;
361- return ControlFlow :: Continue ( ( ) ) ;
413+ match ct. kind ( ) {
414+ ty:: ConstKind :: Param ( param) => {
415+ self . params . insert ( ( param. index , param. name ) ) ;
416+ ControlFlow :: Continue ( ( ) )
417+ }
418+ ty:: ConstKind :: Bound ( db, ty:: BoundVar { .. } ) if db >= self . depth => {
419+ let reported =
420+ self . tcx . dcx ( ) . delayed_bug ( "unexpected escaping late-bound const var" ) ;
421+ ControlFlow :: Break ( reported)
422+ }
423+ _ => ct. super_visit_with ( self ) ,
362424 }
363- ct. super_visit_with ( self )
364425 }
365426 }
366427
367- reported. unwrap_or_else ( || bug ! ( "failed to find gen params in ty" ) )
428+ reported. unwrap_or_else ( || bug ! ( "failed to find gen params or bound vars in ty" ) )
368429}
369430
370431fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments