@@ -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
@@ -316,8 +311,15 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
316
311
ty : Ty < ' tcx > ,
317
312
hir_id : HirId ,
318
313
) -> ErrorGuaranteed {
319
- let mut collector = GenericParamCollector { params : Default :: default ( ) } ;
320
- ty. visit_with ( & mut collector) ;
314
+ let mut collector = GenericParamAndBoundVarCollector {
315
+ tcx,
316
+ params : Default :: default ( ) ,
317
+ vars : Default :: default ( ) ,
318
+ depth : ty:: INNERMOST ,
319
+ } ;
320
+ if let ControlFlow :: Break ( reported) = ty. visit_with ( & mut collector) {
321
+ return reported;
322
+ }
321
323
322
324
let mut reported = None ;
323
325
@@ -334,40 +336,101 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
334
336
param_defined_here_label : tcx. def_ident_span ( param_def. def_id ) . unwrap ( ) ,
335
337
} ) ) ;
336
338
}
339
+ for ( var_def_id, var_name) in collector. vars {
340
+ reported. get_or_insert ( tcx. dcx ( ) . emit_err (
341
+ crate :: errors:: EscapingBoundVarInTyOfAssocConstBinding {
342
+ span : assoc_const. span ,
343
+ assoc_const,
344
+ var_name,
345
+ var_def_kind : tcx. def_descr ( var_def_id) ,
346
+ var_defined_here_label : tcx. def_ident_span ( var_def_id) . unwrap ( ) ,
347
+ } ,
348
+ ) ) ;
349
+ }
337
350
338
- struct GenericParamCollector {
351
+ struct GenericParamAndBoundVarCollector < ' tcx > {
352
+ tcx : TyCtxt < ' tcx > ,
339
353
params : FxIndexSet < ( u32 , Symbol ) > ,
354
+ vars : FxIndexSet < ( DefId , Symbol ) > ,
355
+ depth : ty:: DebruijnIndex ,
340
356
}
341
357
342
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamCollector {
343
- type BreakTy = !;
358
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for GenericParamAndBoundVarCollector < ' tcx > {
359
+ type BreakTy = ErrorGuaranteed ;
360
+
361
+ fn visit_binder < T : TypeVisitable < TyCtxt < ' tcx > > > (
362
+ & mut self ,
363
+ binder : & ty:: Binder < ' tcx , T > ,
364
+ ) -> ControlFlow < Self :: BreakTy > {
365
+ self . depth . shift_in ( 1 ) ;
366
+ let binder = binder. super_visit_with ( self ) ;
367
+ self . depth . shift_out ( 1 ) ;
368
+ binder
369
+ }
344
370
345
371
fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
346
- if let ty:: Param ( param) = ty. kind ( ) {
347
- self . params . insert ( ( param. index , param. name ) ) ;
348
- return ControlFlow :: Continue ( ( ) ) ;
372
+ match ty. kind ( ) {
373
+ ty:: Param ( param) => {
374
+ self . params . insert ( ( param. index , param. name ) ) ;
375
+ }
376
+ ty:: Bound ( db, bt) if * db >= self . depth => {
377
+ self . vars . insert ( match bt. kind {
378
+ ty:: BoundTyKind :: Param ( def_id, name) => ( def_id, name) ,
379
+ ty:: BoundTyKind :: Anon => {
380
+ let reported = self . tcx . dcx ( ) . span_delayed_bug (
381
+ DUMMY_SP ,
382
+ format ! ( "unexpected anon bound ty: {:?}" , bt. var) ,
383
+ ) ;
384
+ return ControlFlow :: Break ( reported) ;
385
+ }
386
+ } ) ;
387
+ }
388
+ _ => return ty. super_visit_with ( self ) ,
349
389
}
350
- ty . super_visit_with ( self )
390
+ ControlFlow :: Continue ( ( ) )
351
391
}
352
392
353
393
fn visit_region ( & mut self , re : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
354
- if let ty:: ReEarlyParam ( param) = re. kind ( ) {
355
- self . params . insert ( ( param. index , param. name ) ) ;
356
- return ControlFlow :: Continue ( ( ) ) ;
394
+ match re. kind ( ) {
395
+ ty:: ReEarlyParam ( param) => {
396
+ self . params . insert ( ( param. index , param. name ) ) ;
397
+ }
398
+ ty:: ReBound ( db, br) if db >= self . depth => {
399
+ self . vars . insert ( match br. kind {
400
+ ty:: BrNamed ( def_id, name) => ( def_id, name) ,
401
+ ty:: BrAnon | ty:: BrEnv => {
402
+ let reported = self . tcx . dcx ( ) . span_delayed_bug (
403
+ DUMMY_SP ,
404
+ format ! ( "unexpected bound region kind: {:?}" , br. kind) ,
405
+ ) ;
406
+ return ControlFlow :: Break ( reported) ;
407
+ }
408
+ } ) ;
409
+ }
410
+ _ => { }
357
411
}
358
412
ControlFlow :: Continue ( ( ) )
359
413
}
360
414
361
415
fn visit_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
362
- if let ty:: ConstKind :: Param ( param) = ct. kind ( ) {
363
- self . params . insert ( ( param. index , param. name ) ) ;
364
- return ControlFlow :: Continue ( ( ) ) ;
416
+ match ct. kind ( ) {
417
+ ty:: ConstKind :: Param ( param) => {
418
+ self . params . insert ( ( param. index , param. name ) ) ;
419
+ ControlFlow :: Continue ( ( ) )
420
+ }
421
+ ty:: ConstKind :: Bound ( db, ty:: BoundVar { .. } ) if db >= self . depth => {
422
+ let reported = self . tcx . dcx ( ) . span_delayed_bug (
423
+ DUMMY_SP ,
424
+ "late-bound const params are not supported yet" ,
425
+ ) ;
426
+ ControlFlow :: Break ( reported)
427
+ }
428
+ _ => ct. super_visit_with ( self ) ,
365
429
}
366
- ct. super_visit_with ( self )
367
430
}
368
431
}
369
432
370
- reported. unwrap_or_else ( || bug ! ( "failed to find gen params in ty" ) )
433
+ reported. unwrap_or_else ( || bug ! ( "failed to find gen params or bound vars in ty" ) )
371
434
}
372
435
373
436
fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments