@@ -50,7 +50,7 @@ impl RegionExt for ResolvedArg {
5050
5151 fn id ( & self ) -> Option < DefId > {
5252 match * self {
53- ResolvedArg :: StaticLifetime => None ,
53+ ResolvedArg :: StaticLifetime | ResolvedArg :: Error ( _ ) => None ,
5454
5555 ResolvedArg :: EarlyBound ( id)
5656 | ResolvedArg :: LateBound ( _, _, id)
@@ -336,7 +336,57 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
336336 }
337337 }
338338 }
339+
340+ fn visit_poly_trait_ref_inner (
341+ & mut self ,
342+ trait_ref : & ' tcx hir:: PolyTraitRef < ' tcx > ,
343+ non_lifetime_binder_allowed : NonLifetimeBinderAllowed ,
344+ ) {
345+ debug ! ( "visit_poly_trait_ref(trait_ref={:?})" , trait_ref) ;
346+
347+ let ( mut binders, scope_type) = self . poly_trait_ref_binder_info ( ) ;
348+
349+ let initial_bound_vars = binders. len ( ) as u32 ;
350+ let mut bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = FxIndexMap :: default ( ) ;
351+ let binders_iter =
352+ trait_ref. bound_generic_params . iter ( ) . enumerate ( ) . map ( |( late_bound_idx, param) | {
353+ let pair = ResolvedArg :: late ( initial_bound_vars + late_bound_idx as u32 , param) ;
354+ let r = late_arg_as_bound_arg ( self . tcx , & pair. 1 , param) ;
355+ bound_vars. insert ( pair. 0 , pair. 1 ) ;
356+ r
357+ } ) ;
358+ binders. extend ( binders_iter) ;
359+
360+ if let NonLifetimeBinderAllowed :: Deny ( where_) = non_lifetime_binder_allowed {
361+ deny_non_region_late_bound ( self . tcx , & mut bound_vars, where_) ;
362+ }
363+
364+ debug ! ( ?binders) ;
365+ self . record_late_bound_vars ( trait_ref. trait_ref . hir_ref_id , binders) ;
366+
367+ // Always introduce a scope here, even if this is in a where clause and
368+ // we introduced the binders around the bounded Ty. In that case, we
369+ // just reuse the concatenation functionality also present in nested trait
370+ // refs.
371+ let scope = Scope :: Binder {
372+ hir_id : trait_ref. trait_ref . hir_ref_id ,
373+ bound_vars,
374+ s : self . scope ,
375+ scope_type,
376+ where_bound_origin : None ,
377+ } ;
378+ self . with ( scope, |this| {
379+ walk_list ! ( this, visit_generic_param, trait_ref. bound_generic_params) ;
380+ this. visit_trait_ref ( & trait_ref. trait_ref ) ;
381+ } ) ;
382+ }
383+ }
384+
385+ enum NonLifetimeBinderAllowed {
386+ Deny ( & ' static str ) ,
387+ Allow ,
339388}
389+
340390impl < ' a , ' tcx > Visitor < ' tcx > for BoundVarContext < ' a , ' tcx > {
341391 type NestedFilter = nested_filter:: OnlyBodies ;
342392
@@ -400,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
400450 }
401451 }
402452
403- let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
453+ let ( mut bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
404454 bound_generic_params
405455 . iter ( )
406456 . enumerate ( )
@@ -411,6 +461,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
411461 } )
412462 . unzip ( ) ;
413463
464+ deny_non_region_late_bound ( self . tcx , & mut bound_vars, "closures" ) ;
465+
414466 self . record_late_bound_vars ( e. hir_id , binders) ;
415467 let scope = Scope :: Binder {
416468 hir_id : e. hir_id ,
@@ -567,7 +619,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
567619 fn visit_ty ( & mut self , ty : & ' tcx hir:: Ty < ' tcx > ) {
568620 match ty. kind {
569621 hir:: TyKind :: BareFn ( c) => {
570- let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) = c
622+ let ( mut bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) = c
571623 . generic_params
572624 . iter ( )
573625 . enumerate ( )
@@ -577,6 +629,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
577629 ( pair, r)
578630 } )
579631 . unzip ( ) ;
632+
633+ deny_non_region_late_bound ( self . tcx , & mut bound_vars, "function pointer types" ) ;
634+
580635 self . record_late_bound_vars ( ty. hir_id , binders) ;
581636 let scope = Scope :: Binder {
582637 hir_id : ty. hir_id ,
@@ -596,7 +651,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
596651 let scope = Scope :: TraitRefBoundary { s : self . scope } ;
597652 self . with ( scope, |this| {
598653 for bound in bounds {
599- this. visit_poly_trait_ref ( bound) ;
654+ this. visit_poly_trait_ref_inner (
655+ bound,
656+ NonLifetimeBinderAllowed :: Deny ( "trait object types" ) ,
657+ ) ;
600658 }
601659 } ) ;
602660 match lifetime. res {
@@ -967,39 +1025,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
9671025 }
9681026
9691027 fn visit_poly_trait_ref ( & mut self , trait_ref : & ' tcx hir:: PolyTraitRef < ' tcx > ) {
970- debug ! ( "visit_poly_trait_ref(trait_ref={:?})" , trait_ref) ;
971-
972- let ( mut binders, scope_type) = self . poly_trait_ref_binder_info ( ) ;
973-
974- let initial_bound_vars = binders. len ( ) as u32 ;
975- let mut bound_vars: FxIndexMap < LocalDefId , ResolvedArg > = FxIndexMap :: default ( ) ;
976- let binders_iter =
977- trait_ref. bound_generic_params . iter ( ) . enumerate ( ) . map ( |( late_bound_idx, param) | {
978- let pair = ResolvedArg :: late ( initial_bound_vars + late_bound_idx as u32 , param) ;
979- let r = late_arg_as_bound_arg ( self . tcx , & pair. 1 , param) ;
980- bound_vars. insert ( pair. 0 , pair. 1 ) ;
981- r
982- } ) ;
983- binders. extend ( binders_iter) ;
984-
985- debug ! ( ?binders) ;
986- self . record_late_bound_vars ( trait_ref. trait_ref . hir_ref_id , binders) ;
987-
988- // Always introduce a scope here, even if this is in a where clause and
989- // we introduced the binders around the bounded Ty. In that case, we
990- // just reuse the concatenation functionality also present in nested trait
991- // refs.
992- let scope = Scope :: Binder {
993- hir_id : trait_ref. trait_ref . hir_ref_id ,
994- bound_vars,
995- s : self . scope ,
996- scope_type,
997- where_bound_origin : None ,
998- } ;
999- self . with ( scope, |this| {
1000- walk_list ! ( this, visit_generic_param, trait_ref. bound_generic_params) ;
1001- this. visit_trait_ref ( & trait_ref. trait_ref ) ;
1002- } ) ;
1028+ self . visit_poly_trait_ref_inner ( trait_ref, NonLifetimeBinderAllowed :: Allow ) ;
10031029 }
10041030}
10051031
@@ -1364,7 +1390,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13641390 return ;
13651391 }
13661392
1367- span_bug ! ( self . tcx. hir( ) . span( hir_id) , "could not resolve {param_def_id:?}" , ) ;
1393+ self . tcx
1394+ . sess
1395+ . delay_span_bug ( self . tcx . hir ( ) . span ( hir_id) , "could not resolve {param_def_id:?}" ) ;
13681396 }
13691397
13701398 #[ instrument( level = "debug" , skip( self ) ) ]
@@ -1915,3 +1943,37 @@ fn is_late_bound_map(
19151943 }
19161944 }
19171945}
1946+
1947+ pub fn deny_non_region_late_bound (
1948+ tcx : TyCtxt < ' _ > ,
1949+ bound_vars : & mut FxIndexMap < LocalDefId , ResolvedArg > ,
1950+ where_ : & str ,
1951+ ) {
1952+ let mut first = true ;
1953+
1954+ for ( var, arg) in bound_vars {
1955+ let Node :: GenericParam ( param) = tcx. hir ( ) . get_by_def_id ( * var) else {
1956+ bug ! ( ) ;
1957+ } ;
1958+
1959+ let what = match param. kind {
1960+ hir:: GenericParamKind :: Type { .. } => "type" ,
1961+ hir:: GenericParamKind :: Const { .. } => "const" ,
1962+ hir:: GenericParamKind :: Lifetime { .. } => continue ,
1963+ } ;
1964+
1965+ let mut diag = tcx. sess . struct_span_err (
1966+ param. span ,
1967+ format ! ( "late-bound {what} parameter not allowed on {where_}" ) ,
1968+ ) ;
1969+
1970+ let guar = if tcx. features ( ) . non_lifetime_binders && first {
1971+ diag. emit ( )
1972+ } else {
1973+ diag. delay_as_bug ( )
1974+ } ;
1975+
1976+ first = false ;
1977+ * arg = ResolvedArg :: Error ( guar) ;
1978+ }
1979+ }
0 commit comments