@@ -1134,20 +1134,43 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
1134
1134
}
1135
1135
1136
1136
fn type_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Ty < ' tcx > {
1137
+ checked_type_of ( tcx, def_id, true ) . unwrap ( )
1138
+ }
1139
+
1140
+ /// Same as [`type_of`] but returns [`Option`] instead of failing.
1141
+ ///
1142
+ /// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
1143
+ /// you'd better just call [`type_of`] directly.
1144
+ pub fn checked_type_of < ' a , ' tcx > (
1145
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1146
+ def_id : DefId ,
1147
+ fail : bool ,
1148
+ ) -> Option < Ty < ' tcx > > {
1137
1149
use rustc:: hir:: * ;
1138
1150
1139
- let hir_id = tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ;
1151
+ let hir_id = match tcx. hir ( ) . as_local_hir_id ( def_id) {
1152
+ Some ( hir_id) => hir_id,
1153
+ None => {
1154
+ if !fail {
1155
+ return None ;
1156
+ }
1157
+ bug ! ( "invalid node" ) ;
1158
+ }
1159
+ } ;
1140
1160
1141
1161
let icx = ItemCtxt :: new ( tcx, def_id) ;
1142
1162
1143
- match tcx. hir ( ) . get_by_hir_id ( hir_id) {
1163
+ Some ( match tcx. hir ( ) . get_by_hir_id ( hir_id) {
1144
1164
Node :: TraitItem ( item) => match item. node {
1145
1165
TraitItemKind :: Method ( ..) => {
1146
1166
let substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
1147
1167
tcx. mk_fn_def ( def_id, substs)
1148
1168
}
1149
1169
TraitItemKind :: Const ( ref ty, _) | TraitItemKind :: Type ( _, Some ( ref ty) ) => icx. to_ty ( ty) ,
1150
1170
TraitItemKind :: Type ( _, None ) => {
1171
+ if !fail {
1172
+ return None ;
1173
+ }
1151
1174
span_bug ! ( item. span, "associated type missing default" ) ;
1152
1175
}
1153
1176
} ,
@@ -1229,6 +1252,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1229
1252
| ItemKind :: GlobalAsm ( ..)
1230
1253
| ItemKind :: ExternCrate ( ..)
1231
1254
| ItemKind :: Use ( ..) => {
1255
+ if !fail {
1256
+ return None ;
1257
+ }
1232
1258
span_bug ! (
1233
1259
item. span,
1234
1260
"compute_type_of_item: unexpected item type: {:?}" ,
@@ -1267,7 +1293,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1267
1293
..
1268
1294
} ) => {
1269
1295
if gen. is_some ( ) {
1270
- return tcx. typeck_tables_of ( def_id) . node_type ( hir_id) ;
1296
+ return Some ( tcx. typeck_tables_of ( def_id) . node_type ( hir_id) ) ;
1271
1297
}
1272
1298
1273
1299
let substs = ty:: ClosureSubsts {
@@ -1345,6 +1371,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1345
1371
}
1346
1372
// Sanity check to make sure everything is as expected.
1347
1373
if !found_const {
1374
+ if !fail {
1375
+ return None ;
1376
+ }
1348
1377
bug ! ( "no arg matching AnonConst in path" )
1349
1378
}
1350
1379
match path. def {
@@ -1360,24 +1389,37 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1360
1389
for param in & generics. params {
1361
1390
if let ty:: GenericParamDefKind :: Const = param. kind {
1362
1391
if param_index == arg_index {
1363
- return tcx. type_of ( param. def_id ) ;
1392
+ return Some ( tcx. type_of ( param. def_id ) ) ;
1364
1393
}
1365
1394
param_index += 1 ;
1366
1395
}
1367
1396
}
1368
1397
// This is no generic parameter associated with the arg. This is
1369
1398
// probably from an extra arg where one is not needed.
1370
- return tcx. types . err ;
1399
+ return Some ( tcx. types . err ) ;
1371
1400
}
1372
1401
Def :: Err => tcx. types . err ,
1373
- x => bug ! ( "unexpected const parent path def {:?}" , x) ,
1402
+ x => {
1403
+ if !fail {
1404
+ return None ;
1405
+ }
1406
+ bug ! ( "unexpected const parent path def {:?}" , x) ;
1407
+ }
1408
+ }
1409
+ }
1410
+ x => {
1411
+ if !fail {
1412
+ return None ;
1374
1413
}
1414
+ bug ! ( "unexpected const parent path {:?}" , x) ;
1375
1415
}
1376
- x => bug ! ( "unexpected const parent path {:?}" , x) ,
1377
1416
}
1378
1417
}
1379
1418
1380
1419
x => {
1420
+ if !fail {
1421
+ return None ;
1422
+ }
1381
1423
bug ! ( "unexpected const parent in type_of_def_id(): {:?}" , x) ;
1382
1424
}
1383
1425
}
@@ -1388,13 +1430,21 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
1388
1430
hir:: GenericParamKind :: Const { ref ty, .. } => {
1389
1431
icx. to_ty ( ty)
1390
1432
}
1391
- x => bug ! ( "unexpected non-type Node::GenericParam: {:?}" , x) ,
1433
+ x => {
1434
+ if !fail {
1435
+ return None ;
1436
+ }
1437
+ bug ! ( "unexpected non-type Node::GenericParam: {:?}" , x)
1438
+ } ,
1392
1439
} ,
1393
1440
1394
1441
x => {
1442
+ if !fail {
1443
+ return None ;
1444
+ }
1395
1445
bug ! ( "unexpected sort of node in type_of_def_id(): {:?}" , x) ;
1396
1446
}
1397
- }
1447
+ } )
1398
1448
}
1399
1449
1400
1450
fn find_existential_constraints < ' a , ' tcx > (
0 commit comments