@@ -126,6 +126,7 @@ enum Scope<'a> {
126
126
/// fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
127
127
/// ```
128
128
where_bound_origin : Option < hir:: PredicateOrigin > ,
129
+ in_where_predict : bool ,
129
130
} ,
130
131
131
132
/// Lifetimes introduced by a fn are scoped to the call-site for that fn,
@@ -195,7 +196,7 @@ struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
195
196
impl < ' a > fmt:: Debug for TruncatedScopeDebug < ' a > {
196
197
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
197
198
match self . 0 {
198
- Scope :: Binder { bound_vars, scope_type, hir_id, where_bound_origin, s : _ } => f
199
+ Scope :: Binder { bound_vars, scope_type, hir_id, where_bound_origin, s : _, .. } => f
199
200
. debug_struct ( "Binder" )
200
201
. field ( "bound_vars" , bound_vars)
201
202
. field ( "scope_type" , scope_type)
@@ -394,6 +395,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
394
395
s : self . scope ,
395
396
scope_type,
396
397
where_bound_origin : None ,
398
+ in_where_predict : false ,
397
399
} ;
398
400
self . with ( scope, |this| {
399
401
walk_list ! ( this, visit_generic_param, trait_ref. bound_generic_params) ;
@@ -478,14 +480,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
478
480
. unzip ( ) ;
479
481
480
482
deny_non_region_late_bound ( self . tcx , & mut bound_vars, "closures" ) ;
481
-
482
483
self . record_late_bound_vars ( e. hir_id , binders) ;
483
484
let scope = Scope :: Binder {
484
485
hir_id : e. hir_id ,
485
486
bound_vars,
486
487
s : self . scope ,
487
488
scope_type : BinderScopeType :: Normal ,
488
489
where_bound_origin : None ,
490
+ in_where_predict : false ,
489
491
} ;
490
492
491
493
self . with ( scope, |this| {
@@ -577,6 +579,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
577
579
s : this. scope ,
578
580
scope_type : BinderScopeType :: Normal ,
579
581
where_bound_origin : None ,
582
+ in_where_predict : false ,
580
583
} ;
581
584
this. with ( scope, |this| {
582
585
let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -630,14 +633,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
630
633
. unzip ( ) ;
631
634
632
635
deny_non_region_late_bound ( self . tcx , & mut bound_vars, "function pointer types" ) ;
633
-
634
636
self . record_late_bound_vars ( ty. hir_id , binders) ;
635
637
let scope = Scope :: Binder {
636
638
hir_id : ty. hir_id ,
637
639
bound_vars,
638
640
s : self . scope ,
639
641
scope_type : BinderScopeType :: Normal ,
640
642
where_bound_origin : None ,
643
+ in_where_predict : false ,
641
644
} ;
642
645
self . with ( scope, |this| {
643
646
// a bare fn has no bounds, so everything
@@ -907,6 +910,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
907
910
s : self . scope ,
908
911
scope_type : BinderScopeType :: Normal ,
909
912
where_bound_origin : Some ( origin) ,
913
+ in_where_predict : true ,
910
914
} ;
911
915
self . with ( scope, |this| {
912
916
walk_list ! ( this, visit_generic_param, bound_generic_params) ;
@@ -963,14 +967,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
963
967
// of "if there isn't a Binder scope above us, add one", but I
964
968
// imagine there's a better way to go about this.
965
969
let ( binders, scope_type) = self . poly_trait_ref_binder_info ( ) ;
966
-
967
970
self . record_late_bound_vars ( * hir_id, binders) ;
968
971
let scope = Scope :: Binder {
969
972
hir_id : * hir_id,
970
973
bound_vars : FxIndexMap :: default ( ) ,
971
974
s : self . scope ,
972
975
scope_type,
973
976
where_bound_origin : None ,
977
+ in_where_predict : false ,
974
978
} ;
975
979
self . with ( scope, |this| {
976
980
intravisit:: walk_param_bound ( this, bound) ;
@@ -992,6 +996,26 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
992
996
993
997
fn visit_generic_param ( & mut self , p : & ' tcx GenericParam < ' tcx > ) {
994
998
match p. kind {
999
+ GenericParamKind :: Const { ty, default : Some ( default) } => {
1000
+ self . resolve_type_ref ( p. def_id , p. hir_id ) ;
1001
+
1002
+ // For expr in default of Const expr in where predict.
1003
+ // We may get unexpected bound var resolution when converts a hir id
1004
+ // corresponding to a type parameter to a early-bound `ty::Param` or late-bound `ty::Bound`
1005
+ // fn foo<T>() where for<const N: u8 = { T::<0>::A as u8 }> T: Default {}
1006
+ // ^ generic param ty
1007
+ // ^^^^^^ hir_id
1008
+ // ^^^^^^^^^^^^^^^^^^^ default
1009
+ // ^^^ parent_id after twice iterations
1010
+ // ^ generics of parent
1011
+ if let Scope :: Binder { in_where_predict, .. } = self . scope && * in_where_predict {
1012
+ let BoundVarContext { tcx, map, .. } = self ;
1013
+ let wrap_scope = Scope :: LateBoundary { s : self . scope , what : "constant" } ;
1014
+ let mut this = BoundVarContext { tcx : * tcx, map, scope : & wrap_scope } ;
1015
+ this. visit_id ( default. hir_id ) ;
1016
+ this. visit_nested_body ( default. body ) ;
1017
+ }
1018
+ }
995
1019
GenericParamKind :: Type { .. } | GenericParamKind :: Const { .. } => {
996
1020
self . resolve_type_ref ( p. def_id , p. hir_id ) ;
997
1021
}
@@ -1144,6 +1168,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1144
1168
s : self . scope ,
1145
1169
scope_type : BinderScopeType :: Normal ,
1146
1170
where_bound_origin : None ,
1171
+ in_where_predict : false ,
1147
1172
} ;
1148
1173
self . with ( scope, walk) ;
1149
1174
}
@@ -1160,6 +1185,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1160
1185
s : self . scope ,
1161
1186
scope_type : BinderScopeType :: Normal ,
1162
1187
where_bound_origin : None ,
1188
+ in_where_predict : false ,
1163
1189
} ;
1164
1190
self . with ( scope, |this| {
1165
1191
let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1369,7 +1395,6 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1369
1395
let mut late_depth = 0 ;
1370
1396
let mut scope = self . scope ;
1371
1397
let mut crossed_late_boundary = None ;
1372
-
1373
1398
let result = loop {
1374
1399
match * scope {
1375
1400
Scope :: Body { s, .. } => {
0 commit comments