@@ -83,22 +83,17 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
8383 }
8484
8585 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 ( ) ;
8787
8888 // We can't possibly catch this in the resolver, therefore we need to handle it here.
8989 // 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) ;
9793 return Ty :: new_error ( tcx, reported) ;
9894 } ;
9995
100- // FIXME(fmease): Reject escaping late-bound vars.
101- return ty. skip_binder ( ) ;
96+ return ty;
10297 }
10398
10499 // 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>(
325320 ty : Ty < ' tcx > ,
326321 hir_id : HirId ,
327322) -> 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 ( ) ;
332330
333331 let ty_note = ty
334332 . make_suggestable ( tcx, false )
@@ -363,40 +361,100 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
363361 ty_note,
364362 } ) ) ;
365363 }
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+ }
366376
367- struct GenericParamCollector {
377+ struct GenericParamAndBoundVarCollector < ' tcx > {
378+ tcx : TyCtxt < ' tcx > ,
368379 params : FxIndexSet < ( u32 , Symbol ) > ,
380+ vars : FxIndexSet < ( DefId , Symbol ) > ,
381+ depth : ty:: DebruijnIndex ,
369382 }
370383
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+ }
373396
374397 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 ) ,
378415 }
379- ty . super_visit_with ( self )
416+ ControlFlow :: Continue ( ( ) )
380417 }
381418
382419 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+ _ => { }
386437 }
387438 ControlFlow :: Continue ( ( ) )
388439 }
389440
390441 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 ) ,
394453 }
395- ct. super_visit_with ( self )
396454 }
397455 }
398456
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" ) )
400458}
401459
402460fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments