@@ -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
@@ -316,8 +311,15 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
316311 ty : Ty < ' tcx > ,
317312 hir_id : HirId ,
318313) -> 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+ }
321323
322324 let mut reported = None ;
323325
@@ -334,40 +336,101 @@ fn report_overly_generic_assoc_const_binding_type<'tcx>(
334336 param_defined_here_label : tcx. def_ident_span ( param_def. def_id ) . unwrap ( ) ,
335337 } ) ) ;
336338 }
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+ }
337350
338- struct GenericParamCollector {
351+ struct GenericParamAndBoundVarCollector < ' tcx > {
352+ tcx : TyCtxt < ' tcx > ,
339353 params : FxIndexSet < ( u32 , Symbol ) > ,
354+ vars : FxIndexSet < ( DefId , Symbol ) > ,
355+ depth : ty:: DebruijnIndex ,
340356 }
341357
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+ }
344370
345371 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 ) ,
349389 }
350- ty . super_visit_with ( self )
390+ ControlFlow :: Continue ( ( ) )
351391 }
352392
353393 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+ _ => { }
357411 }
358412 ControlFlow :: Continue ( ( ) )
359413 }
360414
361415 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
423+ . tcx
424+ . dcx ( )
425+ . span_delayed_bug ( DUMMY_SP , "unexpected escaping late-bound const var" ) ;
426+ ControlFlow :: Break ( reported)
427+ }
428+ _ => ct. super_visit_with ( self ) ,
365429 }
366- ct. super_visit_with ( self )
367430 }
368431 }
369432
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" ) )
371434}
372435
373436fn get_path_containing_arg_in_pat < ' hir > (
0 commit comments