@@ -71,22 +71,17 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
71
71
}
72
72
73
73
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 ( ) ;
75
75
76
76
// We can't possibly catch this in the resolver, therefore we need to handle it here.
77
77
// 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) ;
85
81
return Ty :: new_error ( tcx, reported) ;
86
82
} ;
87
83
88
- // FIXME(fmease): Reject escaping late-bound vars.
89
- return ty. skip_binder ( ) ;
84
+ return ty;
90
85
}
91
86
92
87
// 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>(
313
308
ty : Ty < ' tcx > ,
314
309
hir_id : HirId ,
315
310
) -> 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
+ }
318
320
319
321
let mut reported = None ;
320
322
@@ -331,40 +333,99 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
331
333
param_defined_here_label : tcx. def_ident_span ( param_def. def_id ) . unwrap ( ) ,
332
334
} ) ) ;
333
335
}
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
+ }
334
347
335
- struct GenericParamCollector {
348
+ struct GenericParamAndBoundVarCollector < ' tcx > {
349
+ tcx : TyCtxt < ' tcx > ,
336
350
params : FxIndexSet < ( u32 , Symbol ) > ,
351
+ vars : FxIndexSet < ( DefId , Symbol ) > ,
352
+ depth : ty:: DebruijnIndex ,
337
353
}
338
354
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
+ }
341
367
342
368
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 ) ,
346
386
}
347
- ty . super_visit_with ( self )
387
+ ControlFlow :: Continue ( ( ) )
348
388
}
349
389
350
390
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
+ _ => { }
354
408
}
355
409
ControlFlow :: Continue ( ( ) )
356
410
}
357
411
358
412
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 ) ,
362
424
}
363
- ct. super_visit_with ( self )
364
425
}
365
426
}
366
427
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" ) )
368
429
}
369
430
370
431
fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments