@@ -1250,6 +1250,11 @@ impl<T: HasInterner> Binders<T> {
1250
1250
Self { binders, value }
1251
1251
}
1252
1252
1253
+ pub fn empty ( interner : & T :: Interner , value : T ) -> Self {
1254
+ let binders = ParameterKinds :: new ( interner) ;
1255
+ Self { binders, value }
1256
+ }
1257
+
1253
1258
/// Skips the binder and returns the "bound" value. This is a
1254
1259
/// risky thing to do because it's easy to get confused about
1255
1260
/// De Bruijn indices and the like. `skip_binder` is only valid
@@ -1287,6 +1292,18 @@ impl<T: HasInterner> Binders<T> {
1287
1292
}
1288
1293
}
1289
1294
1295
+ pub fn filter_map < U , OP > ( self , op : OP ) -> Option < Binders < U > >
1296
+ where
1297
+ OP : FnOnce ( T ) -> Option < U > ,
1298
+ U : HasInterner < Interner = T :: Interner > ,
1299
+ {
1300
+ let value = op ( self . value ) ?;
1301
+ Some ( Binders {
1302
+ binders : self . binders ,
1303
+ value,
1304
+ } )
1305
+ }
1306
+
1290
1307
pub fn map_ref < ' a , U , OP > ( & ' a self , op : OP ) -> Binders < U >
1291
1308
where
1292
1309
OP : FnOnce ( & ' a T ) -> U ,
@@ -1295,6 +1312,19 @@ impl<T: HasInterner> Binders<T> {
1295
1312
self . as_ref ( ) . map ( op)
1296
1313
}
1297
1314
1315
+ /// Creates a `Substitution` containing bound vars such that applying this
1316
+ /// substitution will not change the value, i.e. `^0.0, ^0.1, ^0.2` and so
1317
+ /// on.
1318
+ pub fn identity_substitution ( & self , interner : & T :: Interner ) -> Substitution < T :: Interner > {
1319
+ Substitution :: from (
1320
+ interner,
1321
+ self . binders
1322
+ . iter ( interner)
1323
+ . enumerate ( )
1324
+ . map ( |( i, pk) | ( pk, i) . to_parameter ( interner) ) ,
1325
+ )
1326
+ }
1327
+
1298
1328
/// Creates a fresh binders that contains a single type
1299
1329
/// variable. The result of the closure will be embedded in this
1300
1330
/// binder. Note that you should be careful with what you return
@@ -1317,6 +1347,36 @@ impl<T: HasInterner> Binders<T> {
1317
1347
}
1318
1348
}
1319
1349
1350
+ impl < T , I > Binders < Binders < T > >
1351
+ where
1352
+ T : Fold < I , I > + HasInterner < Interner = I > ,
1353
+ T :: Result : HasInterner < Interner = I > ,
1354
+ I : Interner ,
1355
+ {
1356
+ /// This turns two levels of binders (`for<A> for<B>`) into one level (`for<A, B>`).
1357
+ pub fn fuse_binders ( self , interner : & T :: Interner ) -> Binders < T :: Result > {
1358
+ let num_binders = self . len ( interner) ;
1359
+ // generate a substitution to shift the indexes of the inner binder:
1360
+ let subst = Substitution :: from (
1361
+ interner,
1362
+ self . value
1363
+ . binders
1364
+ . iter ( interner)
1365
+ . enumerate ( )
1366
+ . map ( |( i, pk) | ( pk, i + num_binders) . to_parameter ( interner) ) ,
1367
+ ) ;
1368
+ let value = self . value . substitute ( interner, & subst) ;
1369
+ let binders = ParameterKinds :: from (
1370
+ interner,
1371
+ self . binders
1372
+ . iter ( interner)
1373
+ . chain ( self . value . binders . iter ( interner) )
1374
+ . cloned ( ) ,
1375
+ ) ;
1376
+ Binders { binders, value }
1377
+ }
1378
+ }
1379
+
1320
1380
impl < T : HasInterner > From < Binders < T > > for ( ParameterKinds < T :: Interner > , T ) {
1321
1381
fn from ( binders : Binders < T > ) -> Self {
1322
1382
( binders. binders , binders. value )
@@ -2073,6 +2133,40 @@ where
2073
2133
}
2074
2134
}
2075
2135
2136
+ pub trait ToParameter {
2137
+ /// Utility for converting a list of all the binders into scope
2138
+ /// into references to those binders. Simply pair the binders with
2139
+ /// the indices, and invoke `to_parameter()` on the `(binder,
2140
+ /// index)` pair. The result will be a reference to a bound
2141
+ /// variable of appropriate kind at the corresponding index.
2142
+ fn to_parameter < I : Interner > ( & self , interner : & I ) -> Parameter < I > {
2143
+ self . to_parameter_at_depth ( interner, DebruijnIndex :: INNERMOST )
2144
+ }
2145
+
2146
+ fn to_parameter_at_depth < I : Interner > (
2147
+ & self ,
2148
+ interner : & I ,
2149
+ debruijn : DebruijnIndex ,
2150
+ ) -> Parameter < I > ;
2151
+ }
2152
+
2153
+ impl < ' a > ToParameter for ( & ' a ParameterKind < ( ) > , usize ) {
2154
+ fn to_parameter_at_depth < I : Interner > (
2155
+ & self ,
2156
+ interner : & I ,
2157
+ debruijn : DebruijnIndex ,
2158
+ ) -> Parameter < I > {
2159
+ let & ( binder, index) = self ;
2160
+ let bound_var = BoundVar :: new ( debruijn, index) ;
2161
+ match * binder {
2162
+ ParameterKind :: Lifetime ( _) => LifetimeData :: BoundVar ( bound_var)
2163
+ . intern ( interner)
2164
+ . cast ( interner) ,
2165
+ ParameterKind :: Ty ( _) => TyData :: BoundVar ( bound_var) . intern ( interner) . cast ( interner) ,
2166
+ }
2167
+ }
2168
+ }
2169
+
2076
2170
impl < ' i , I : Interner > Folder < ' i , I > for & SubstFolder < ' i , I > {
2077
2171
fn as_dyn ( & mut self ) -> & mut dyn Folder < ' i , I > {
2078
2172
self
0 commit comments