@@ -83,22 +83,17 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
83
83
}
84
84
85
85
Node :: TypeBinding ( & TypeBinding { hir_id, ident, .. } ) => {
86
- let ty = tcx. type_of_assoc_const_binding ( hir_id) ;
86
+ let ty = tcx. type_of_assoc_const_binding ( hir_id) . skip_binder ( ) . skip_binder ( ) ;
87
87
88
88
// We can't possibly catch this in the resolver, therefore we need to handle it here.
89
89
// FIXME(const_generics): Support generic const generics.
90
- let Some ( ty) = ty. no_bound_vars ( ) else {
91
- let reported = report_overly_generic_assoc_const_binding_type (
92
- tcx,
93
- ident,
94
- ty. skip_binder ( ) . skip_binder ( ) ,
95
- hir_id,
96
- ) ;
90
+ if ty. has_param ( ) || ty. has_escaping_bound_vars ( ) {
91
+ let reported =
92
+ report_overly_generic_assoc_const_binding_type ( tcx, ident, ty, hir_id) ;
97
93
return Ty :: new_error ( tcx, reported) ;
98
94
} ;
99
95
100
- // FIXME(fmease): Reject escaping late-bound vars.
101
- return ty. skip_binder ( ) ;
96
+ return ty;
102
97
}
103
98
104
99
// This match arm is for when the def_id appears in a GAT whose
@@ -325,10 +320,13 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
325
320
ty : Ty < ' tcx > ,
326
321
hir_id : HirId ,
327
322
) -> ErrorGuaranteed {
328
- let mut collector = GenericParamCollector { params : Default :: default ( ) } ;
329
- ty. visit_with ( & mut collector) ;
330
-
331
- let mut reported = None ;
323
+ let mut collector = GenericParamAndBoundVarCollector {
324
+ tcx,
325
+ params : Default :: default ( ) ,
326
+ vars : Default :: default ( ) ,
327
+ depth : ty:: INNERMOST ,
328
+ } ;
329
+ let mut reported = ty. visit_with ( & mut collector) . break_value ( ) ;
332
330
333
331
let ty_note = ty
334
332
. make_suggestable ( tcx, false )
@@ -363,40 +361,100 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
363
361
ty_note,
364
362
} ) ) ;
365
363
}
364
+ for ( var_def_id, var_name) in collector. vars {
365
+ reported. get_or_insert ( tcx. dcx ( ) . emit_err (
366
+ crate :: errors:: EscapingBoundVarInTyOfAssocConstBinding {
367
+ span : assoc_const. span ,
368
+ assoc_const,
369
+ var_name,
370
+ var_def_kind : tcx. def_descr ( var_def_id) ,
371
+ var_defined_here_label : tcx. def_ident_span ( var_def_id) . unwrap ( ) ,
372
+ ty_note,
373
+ } ,
374
+ ) ) ;
375
+ }
366
376
367
- struct GenericParamCollector {
377
+ struct GenericParamAndBoundVarCollector < ' tcx > {
378
+ tcx : TyCtxt < ' tcx > ,
368
379
params : FxIndexSet < ( u32 , Symbol ) > ,
380
+ vars : FxIndexSet < ( DefId , Symbol ) > ,
381
+ depth : ty:: DebruijnIndex ,
369
382
}
370
383
371
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamCollector {
372
- type BreakTy = !;
384
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamAndBoundVarCollector < ' tcx > {
385
+ type BreakTy = ErrorGuaranteed ;
386
+
387
+ fn visit_binder < T : TypeVisitable < TyCtxt < ' tcx > > > (
388
+ & mut self ,
389
+ binder : & ty:: Binder < ' tcx , T > ,
390
+ ) -> ControlFlow < Self :: BreakTy > {
391
+ self . depth . shift_in ( 1 ) ;
392
+ let binder = binder. super_visit_with ( self ) ;
393
+ self . depth . shift_out ( 1 ) ;
394
+ binder
395
+ }
373
396
374
397
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
375
- if let ty:: Param ( param) = ty. kind ( ) {
376
- self . params . insert ( ( param. index , param. name ) ) ;
377
- return ControlFlow :: Continue ( ( ) ) ;
398
+ match ty. kind ( ) {
399
+ ty:: Param ( param) => {
400
+ self . params . insert ( ( param. index , param. name ) ) ;
401
+ }
402
+ ty:: Bound ( db, bt) if * db >= self . depth => {
403
+ self . vars . insert ( match bt. kind {
404
+ ty:: BoundTyKind :: Param ( def_id, name) => ( def_id, name) ,
405
+ ty:: BoundTyKind :: Anon => {
406
+ let reported = self
407
+ . tcx
408
+ . dcx ( )
409
+ . delayed_bug ( format ! ( "unexpected anon bound ty: {:?}" , bt. var) ) ;
410
+ return ControlFlow :: Break ( reported) ;
411
+ }
412
+ } ) ;
413
+ }
414
+ _ => return ty. super_visit_with ( self ) ,
378
415
}
379
- ty . super_visit_with ( self )
416
+ ControlFlow :: Continue ( ( ) )
380
417
}
381
418
382
419
fn visit_region ( & mut self , re : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
383
- if let ty:: ReEarlyParam ( param) = re. kind ( ) {
384
- self . params . insert ( ( param. index , param. name ) ) ;
385
- return ControlFlow :: Continue ( ( ) ) ;
420
+ match re. kind ( ) {
421
+ ty:: ReEarlyParam ( param) => {
422
+ self . params . insert ( ( param. index , param. name ) ) ;
423
+ }
424
+ ty:: ReBound ( db, br) if db >= self . depth => {
425
+ self . vars . insert ( match br. kind {
426
+ ty:: BrNamed ( def_id, name) => ( def_id, name) ,
427
+ ty:: BrAnon | ty:: BrEnv => {
428
+ let reported = self . tcx . dcx ( ) . delayed_bug ( format ! (
429
+ "unexpected bound region kind: {:?}" ,
430
+ br. kind
431
+ ) ) ;
432
+ return ControlFlow :: Break ( reported) ;
433
+ }
434
+ } ) ;
435
+ }
436
+ _ => { }
386
437
}
387
438
ControlFlow :: Continue ( ( ) )
388
439
}
389
440
390
441
fn visit_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
391
- if let ty:: ConstKind :: Param ( param) = ct. kind ( ) {
392
- self . params . insert ( ( param. index , param. name ) ) ;
393
- return ControlFlow :: Continue ( ( ) ) ;
442
+ match ct. kind ( ) {
443
+ ty:: ConstKind :: Param ( param) => {
444
+ self . params . insert ( ( param. index , param. name ) ) ;
445
+ ControlFlow :: Continue ( ( ) )
446
+ }
447
+ ty:: ConstKind :: Bound ( db, ty:: BoundVar { .. } ) if db >= self . depth => {
448
+ let reported =
449
+ self . tcx . dcx ( ) . delayed_bug ( "unexpected escaping late-bound const var" ) ;
450
+ ControlFlow :: Break ( reported)
451
+ }
452
+ _ => ct. super_visit_with ( self ) ,
394
453
}
395
- ct. super_visit_with ( self )
396
454
}
397
455
}
398
456
399
- reported. unwrap_or_else ( || bug ! ( "failed to find gen params in ty" ) )
457
+ reported. unwrap_or_else ( || bug ! ( "failed to find gen params or bound vars in ty" ) )
400
458
}
401
459
402
460
fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments