@@ -50,7 +50,7 @@ impl RegionExt for ResolvedArg {
50
50
51
51
fn id ( & self ) -> Option < DefId > {
52
52
match * self {
53
- ResolvedArg :: StaticLifetime => None ,
53
+ ResolvedArg :: StaticLifetime | ResolvedArg :: Error ( _ ) => None ,
54
54
55
55
ResolvedArg :: EarlyBound ( id)
56
56
| ResolvedArg :: LateBound ( _, _, id)
@@ -336,7 +336,57 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
336
336
}
337
337
}
338
338
}
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 ,
339
388
}
389
+
340
390
impl < ' a , ' tcx > Visitor < ' tcx > for BoundVarContext < ' a , ' tcx > {
341
391
type NestedFilter = nested_filter:: OnlyBodies ;
342
392
@@ -400,7 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
400
450
}
401
451
}
402
452
403
- let ( bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
453
+ let ( mut bound_vars, binders) : ( FxIndexMap < LocalDefId , ResolvedArg > , Vec < _ > ) =
404
454
bound_generic_params
405
455
. iter ( )
406
456
. enumerate ( )
@@ -411,6 +461,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
411
461
} )
412
462
. unzip ( ) ;
413
463
464
+ deny_non_region_late_bound ( self . tcx , & mut bound_vars, "closures" ) ;
465
+
414
466
self . record_late_bound_vars ( e. hir_id , binders) ;
415
467
let scope = Scope :: Binder {
416
468
hir_id : e. hir_id ,
@@ -567,7 +619,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
567
619
fn visit_ty ( & mut self , ty : & ' tcx hir:: Ty < ' tcx > ) {
568
620
match ty. kind {
569
621
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
571
623
. generic_params
572
624
. iter ( )
573
625
. enumerate ( )
@@ -577,6 +629,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
577
629
( pair, r)
578
630
} )
579
631
. unzip ( ) ;
632
+
633
+ deny_non_region_late_bound ( self . tcx , & mut bound_vars, "function pointer types" ) ;
634
+
580
635
self . record_late_bound_vars ( ty. hir_id , binders) ;
581
636
let scope = Scope :: Binder {
582
637
hir_id : ty. hir_id ,
@@ -596,7 +651,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
596
651
let scope = Scope :: TraitRefBoundary { s : self . scope } ;
597
652
self . with ( scope, |this| {
598
653
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
+ ) ;
600
658
}
601
659
} ) ;
602
660
match lifetime. res {
@@ -967,39 +1025,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
967
1025
}
968
1026
969
1027
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 ) ;
1003
1029
}
1004
1030
}
1005
1031
@@ -1364,7 +1390,9 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1364
1390
return ;
1365
1391
}
1366
1392
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:?}" ) ;
1368
1396
}
1369
1397
1370
1398
#[ instrument( level = "debug" , skip( self ) ) ]
@@ -1915,3 +1943,37 @@ fn is_late_bound_map(
1915
1943
}
1916
1944
}
1917
1945
}
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