Skip to content

Commit 1842886

Browse files
committed
Infallible version of type_of.
1 parent fcd6f20 commit 1842886

File tree

22 files changed

+191
-281
lines changed

22 files changed

+191
-281
lines changed

compiler/rustc_incremental/src/persist/dirty_clean.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ const CFG: Symbol = sym::cfg;
3737
// Base and Extra labels to build up the labels
3838

3939
/// For typedef, constants, and statics
40-
const BASE_CONST: &[&str] = &[label_strs::type_of];
40+
const BASE_CONST: &[&str] = &[label_strs::try_type_of];
4141

4242
/// DepNodes for functions + methods
4343
const BASE_FN: &[&str] = &[
4444
// Callers will depend on the signature of these items, so we better test
4545
label_strs::fn_sig,
4646
label_strs::generics_of,
4747
label_strs::predicates_of,
48-
label_strs::type_of,
48+
label_strs::try_type_of,
4949
// And a big part of compilation (that we eventually want to cache) is type inference
5050
// information:
5151
label_strs::typeck,
@@ -71,7 +71,7 @@ const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir]
7171
/// Note that changing the type of a field does not change the type of the struct or enum, but
7272
/// adding/removing fields or changing a fields name or visibility does.
7373
const BASE_STRUCT: &[&str] =
74-
&[label_strs::generics_of, label_strs::predicates_of, label_strs::type_of];
74+
&[label_strs::generics_of, label_strs::predicates_of, label_strs::try_type_of];
7575

7676
/// Trait definition `DepNode`s.
7777
const BASE_TRAIT_DEF: &[&str] = &[

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl IntoArgs for (CrateNum, DefId) {
9090
}
9191

9292
provide! { <'tcx> tcx, def_id, other, cdata,
93-
type_of => { cdata.get_type(def_id.index, tcx) }
93+
try_type_of => { Ok(cdata.get_type(def_id.index, tcx)) }
9494
generics_of => { cdata.get_generics(def_id.index, tcx.sess) }
9595
explicit_predicates_of => { cdata.get_explicit_predicates(def_id.index, tcx) }
9696
inferred_outlives_of => { cdata.get_inferred_outlives(def_id.index, tcx) }

compiler/rustc_middle/src/query/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ rustc_queries! {
9494
}
9595

9696
/// Records the type of every item.
97-
query type_of(key: DefId) -> Ty<'tcx> {
97+
query try_type_of(key: DefId) -> Result<Ty<'tcx>, String> {
9898
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
9999
cache_on_disk_if { key.is_local() }
100100
}

compiler/rustc_middle/src/ty/query/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ impl TyCtxt<'tcx> {
312312
self.opt_def_kind(def_id)
313313
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
314314
}
315+
316+
pub fn type_of(self, def_id: impl IntoQueryParam<DefId>) -> Ty<'tcx> {
317+
let def_id = def_id.into_query_param();
318+
self.try_type_of(def_id).unwrap_or_else(|msg| {
319+
let hir_id = self.hir().local_def_id_to_hir_id(def_id.expect_local());
320+
span_bug!(self.def_span(def_id), "type_of: {}: {:?}", msg, self.hir().find(hir_id));
321+
})
322+
}
315323
}
316324

317325
impl TyCtxtAt<'tcx> {
@@ -320,4 +328,12 @@ impl TyCtxtAt<'tcx> {
320328
self.opt_def_kind(def_id)
321329
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
322330
}
331+
332+
pub fn type_of(self, def_id: impl IntoQueryParam<DefId>) -> Ty<'tcx> {
333+
let def_id = def_id.into_query_param();
334+
self.try_type_of(def_id).unwrap_or_else(|msg| {
335+
let hir_id = self.hir().local_def_id_to_hir_id(def_id.expect_local());
336+
span_bug!(self.def_span(def_id), "type_of: {}: {:?}", msg, self.hir().find(hir_id));
337+
})
338+
}
323339
}

compiler/rustc_typeck/src/collect.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
6969
pub fn provide(providers: &mut Providers) {
7070
*providers = Providers {
7171
opt_const_param_of: type_of::opt_const_param_of,
72-
type_of: type_of::type_of,
72+
try_type_of: type_of::try_type_of,
7373
item_bounds: item_bounds::item_bounds,
7474
explicit_item_bounds: item_bounds::explicit_item_bounds,
7575
generics_of,
@@ -251,12 +251,12 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
251251
hir::GenericParamKind::Lifetime { .. } => {}
252252
hir::GenericParamKind::Type { default: Some(_), .. } => {
253253
let def_id = self.tcx.hir().local_def_id(param.hir_id);
254-
self.tcx.ensure().type_of(def_id);
254+
self.tcx.ensure().try_type_of(def_id);
255255
}
256256
hir::GenericParamKind::Type { .. } => {}
257257
hir::GenericParamKind::Const { .. } => {
258258
let def_id = self.tcx.hir().local_def_id(param.hir_id);
259-
self.tcx.ensure().type_of(def_id);
259+
self.tcx.ensure().try_type_of(def_id);
260260
// FIXME(const_generics_defaults)
261261
}
262262
}
@@ -268,7 +268,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
268268
if let hir::ExprKind::Closure(..) = expr.kind {
269269
let def_id = self.tcx.hir().local_def_id(expr.hir_id);
270270
self.tcx.ensure().generics_of(def_id);
271-
self.tcx.ensure().type_of(def_id);
271+
self.tcx.ensure().try_type_of(def_id);
272272
}
273273
intravisit::walk_expr(self, expr);
274274
}
@@ -727,7 +727,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
727727
for item in items {
728728
let item = tcx.hir().foreign_item(item.id);
729729
tcx.ensure().generics_of(item.def_id);
730-
tcx.ensure().type_of(item.def_id);
730+
tcx.ensure().try_type_of(item.def_id);
731731
tcx.ensure().predicates_of(item.def_id);
732732
if let hir::ForeignItemKind::Fn(..) = item.kind {
733733
tcx.ensure().fn_sig(item.def_id);
@@ -736,13 +736,13 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
736736
}
737737
hir::ItemKind::Enum(ref enum_definition, _) => {
738738
tcx.ensure().generics_of(def_id);
739-
tcx.ensure().type_of(def_id);
739+
tcx.ensure().try_type_of(def_id);
740740
tcx.ensure().predicates_of(def_id);
741741
convert_enum_variant_types(tcx, def_id.to_def_id(), &enum_definition.variants);
742742
}
743743
hir::ItemKind::Impl { .. } => {
744744
tcx.ensure().generics_of(def_id);
745-
tcx.ensure().type_of(def_id);
745+
tcx.ensure().try_type_of(def_id);
746746
tcx.ensure().impl_trait_ref(def_id);
747747
tcx.ensure().predicates_of(def_id);
748748
}
@@ -759,13 +759,13 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
759759
}
760760
hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => {
761761
tcx.ensure().generics_of(def_id);
762-
tcx.ensure().type_of(def_id);
762+
tcx.ensure().try_type_of(def_id);
763763
tcx.ensure().predicates_of(def_id);
764764

765765
for f in struct_def.fields() {
766766
let def_id = tcx.hir().local_def_id(f.hir_id);
767767
tcx.ensure().generics_of(def_id);
768-
tcx.ensure().type_of(def_id);
768+
tcx.ensure().try_type_of(def_id);
769769
tcx.ensure().predicates_of(def_id);
770770
}
771771

@@ -790,7 +790,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
790790
| hir::ItemKind::Const(..)
791791
| hir::ItemKind::Fn(..) => {
792792
tcx.ensure().generics_of(def_id);
793-
tcx.ensure().type_of(def_id);
793+
tcx.ensure().try_type_of(def_id);
794794
tcx.ensure().predicates_of(def_id);
795795
match it.kind {
796796
hir::ItemKind::Fn(..) => tcx.ensure().fn_sig(def_id),
@@ -807,16 +807,16 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
807807

808808
match trait_item.kind {
809809
hir::TraitItemKind::Fn(..) => {
810-
tcx.ensure().type_of(trait_item_id.def_id);
810+
tcx.ensure().try_type_of(trait_item_id.def_id);
811811
tcx.ensure().fn_sig(trait_item_id.def_id);
812812
}
813813

814814
hir::TraitItemKind::Const(.., Some(_)) => {
815-
tcx.ensure().type_of(trait_item_id.def_id);
815+
tcx.ensure().try_type_of(trait_item_id.def_id);
816816
}
817817

818818
hir::TraitItemKind::Const(..) => {
819-
tcx.ensure().type_of(trait_item_id.def_id);
819+
tcx.ensure().try_type_of(trait_item_id.def_id);
820820
// Account for `const C: _;`.
821821
let mut visitor = PlaceholderHirTyCollector::default();
822822
visitor.visit_trait_item(trait_item);
@@ -825,7 +825,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
825825

826826
hir::TraitItemKind::Type(_, Some(_)) => {
827827
tcx.ensure().item_bounds(trait_item_id.def_id);
828-
tcx.ensure().type_of(trait_item_id.def_id);
828+
tcx.ensure().try_type_of(trait_item_id.def_id);
829829
// Account for `type T = _;`.
830830
let mut visitor = PlaceholderHirTyCollector::default();
831831
visitor.visit_trait_item(trait_item);
@@ -849,7 +849,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
849849
fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
850850
let def_id = impl_item_id.def_id;
851851
tcx.ensure().generics_of(def_id);
852-
tcx.ensure().type_of(def_id);
852+
tcx.ensure().try_type_of(def_id);
853853
tcx.ensure().predicates_of(def_id);
854854
let impl_item = tcx.hir().impl_item(impl_item_id);
855855
match impl_item.kind {
@@ -870,7 +870,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
870870
fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
871871
let def_id = tcx.hir().local_def_id(ctor_id);
872872
tcx.ensure().generics_of(def_id);
873-
tcx.ensure().type_of(def_id);
873+
tcx.ensure().try_type_of(def_id);
874874
tcx.ensure().predicates_of(def_id);
875875
}
876876

@@ -908,7 +908,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId, variants: &[hir::V
908908
for f in variant.data.fields() {
909909
let def_id = tcx.hir().local_def_id(f.hir_id);
910910
tcx.ensure().generics_of(def_id);
911-
tcx.ensure().type_of(def_id);
911+
tcx.ensure().try_type_of(def_id);
912912
tcx.ensure().predicates_of(def_id);
913913
}
914914

compiler/rustc_typeck/src/collect/type_of.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,16 @@ fn get_path_containing_arg_in_pat<'hir>(
250250
arg_path
251251
}
252252

253-
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
253+
pub(super) fn try_type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Result<Ty<'_>, String> {
254254
let def_id = def_id.expect_local();
255255
use rustc_hir::*;
256256

257257
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
258258

259259
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
260260

261-
match tcx.hir().get(hir_id) {
261+
let node = tcx.hir().find(hir_id).ok_or_else(|| format!("Not found in HIR: {:?}", hir_id))?;
262+
let ty = match node {
262263
Node::TraitItem(item) => match item.kind {
263264
TraitItemKind::Fn(..) => {
264265
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
@@ -275,7 +276,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
275276
.unwrap_or_else(|| icx.to_ty(ty)),
276277
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
277278
TraitItemKind::Type(_, None) => {
278-
span_bug!(item.span, "associated type missing default");
279+
return Err("associated type missing default".to_owned());
279280
}
280281
},
281282

@@ -368,11 +369,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
368369
| ItemKind::GlobalAsm(..)
369370
| ItemKind::ExternCrate(..)
370371
| ItemKind::Use(..) => {
371-
span_bug!(
372-
item.span,
372+
return Err(format!(
373373
"compute_type_of_item: unexpected item type: {:?}",
374374
item.kind
375-
);
375+
));
376376
}
377377
}
378378
}
@@ -388,7 +388,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
388388

389389
Node::Ctor(&ref def) | Node::Variant(Variant { data: ref def, .. }) => match *def {
390390
VariantData::Unit(..) | VariantData::Struct(..) => {
391-
tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id())
391+
return tcx.try_type_of(tcx.hir().get_parent_did(hir_id).to_def_id());
392392
}
393393
VariantData::Tuple(..) => {
394394
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
@@ -411,7 +411,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
411411
if let Some(param) = tcx.opt_const_param_of(def_id) {
412412
// We defer to `type_of` of the corresponding parameter
413413
// for generic arguments.
414-
return tcx.type_of(param);
414+
return tcx.try_type_of(param);
415415
}
416416

417417
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
@@ -446,13 +446,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
446446
Node::GenericParam(param) => match &param.kind {
447447
GenericParamKind::Type { default: Some(ty), .. }
448448
| GenericParamKind::Const { ty, .. } => icx.to_ty(ty),
449-
x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
449+
x => return Err(format!("unexpected non-type Node::GenericParam: {:?}", x)),
450450
},
451451

452452
x => {
453-
bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
453+
return Err(format!("unexpected sort of node in type_of_def_id(): {:?}", x));
454454
}
455-
}
455+
};
456+
Ok(ty)
456457
}
457458

458459
fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {

src/test/incremental/hashes/consts.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub const CONST_VISIBILITY: u8 = 0;
2929
const CONST_CHANGE_TYPE_1: i32 = 0;
3030

3131
#[cfg(not(cfail1))]
32-
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
32+
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,try_type_of")]
3333
#[rustc_clean(cfg="cfail3")]
3434
const CONST_CHANGE_TYPE_1: u32 = 0;
3535

@@ -39,7 +39,7 @@ const CONST_CHANGE_TYPE_1: u32 = 0;
3939
const CONST_CHANGE_TYPE_2: Option<u32> = None;
4040

4141
#[cfg(not(cfail1))]
42-
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
42+
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,try_type_of")]
4343
#[rustc_clean(cfg="cfail3")]
4444
const CONST_CHANGE_TYPE_2: Option<u64> = None;
4545

@@ -99,11 +99,11 @@ mod const_change_type_indirectly {
9999
#[cfg(not(cfail1))]
100100
use super::ReferencedType2 as Type;
101101

102-
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
102+
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,try_type_of")]
103103
#[rustc_clean(cfg="cfail3")]
104104
const CONST_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
105105

106-
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
106+
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,try_type_of")]
107107
#[rustc_clean(cfg="cfail3")]
108108
const CONST_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
109109
}

0 commit comments

Comments
 (0)