@@ -1134,20 +1134,43 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
11341134}
11351135
11361136fn 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 > > {
11371149 use rustc:: hir:: * ;
11381150
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+ } ;
11401160
11411161 let icx = ItemCtxt :: new ( tcx, def_id) ;
11421162
1143- match tcx. hir ( ) . get_by_hir_id ( hir_id) {
1163+ Some ( match tcx. hir ( ) . get_by_hir_id ( hir_id) {
11441164 Node :: TraitItem ( item) => match item. node {
11451165 TraitItemKind :: Method ( ..) => {
11461166 let substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
11471167 tcx. mk_fn_def ( def_id, substs)
11481168 }
11491169 TraitItemKind :: Const ( ref ty, _) | TraitItemKind :: Type ( _, Some ( ref ty) ) => icx. to_ty ( ty) ,
11501170 TraitItemKind :: Type ( _, None ) => {
1171+ if !fail {
1172+ return None ;
1173+ }
11511174 span_bug ! ( item. span, "associated type missing default" ) ;
11521175 }
11531176 } ,
@@ -1229,6 +1252,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
12291252 | ItemKind :: GlobalAsm ( ..)
12301253 | ItemKind :: ExternCrate ( ..)
12311254 | ItemKind :: Use ( ..) => {
1255+ if !fail {
1256+ return None ;
1257+ }
12321258 span_bug ! (
12331259 item. span,
12341260 "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> {
12671293 ..
12681294 } ) => {
12691295 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) ) ;
12711297 }
12721298
12731299 let substs = ty:: ClosureSubsts {
@@ -1345,6 +1371,9 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
13451371 }
13461372 // Sanity check to make sure everything is as expected.
13471373 if !found_const {
1374+ if !fail {
1375+ return None ;
1376+ }
13481377 bug ! ( "no arg matching AnonConst in path" )
13491378 }
13501379 match path. def {
@@ -1360,24 +1389,37 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
13601389 for param in & generics. params {
13611390 if let ty:: GenericParamDefKind :: Const = param. kind {
13621391 if param_index == arg_index {
1363- return tcx. type_of ( param. def_id ) ;
1392+ return Some ( tcx. type_of ( param. def_id ) ) ;
13641393 }
13651394 param_index += 1 ;
13661395 }
13671396 }
13681397 // This is no generic parameter associated with the arg. This is
13691398 // probably from an extra arg where one is not needed.
1370- return tcx. types . err ;
1399+ return Some ( tcx. types . err ) ;
13711400 }
13721401 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 ;
13741413 }
1414+ bug ! ( "unexpected const parent path {:?}" , x) ;
13751415 }
1376- x => bug ! ( "unexpected const parent path {:?}" , x) ,
13771416 }
13781417 }
13791418
13801419 x => {
1420+ if !fail {
1421+ return None ;
1422+ }
13811423 bug ! ( "unexpected const parent in type_of_def_id(): {:?}" , x) ;
13821424 }
13831425 }
@@ -1388,13 +1430,21 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
13881430 hir:: GenericParamKind :: Const { ref ty, .. } => {
13891431 icx. to_ty ( ty)
13901432 }
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+ } ,
13921439 } ,
13931440
13941441 x => {
1442+ if !fail {
1443+ return None ;
1444+ }
13951445 bug ! ( "unexpected sort of node in type_of_def_id(): {:?}" , x) ;
13961446 }
1397- }
1447+ } )
13981448}
13991449
14001450fn find_existential_constraints < ' a , ' tcx > (
0 commit comments