diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index b7f5921438f..414c3ad633e 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -780,7 +780,6 @@ fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { fn get_variant( &self, - tcx: TyCtxt<'tcx>, kind: &EntryKind, index: DefIndex, parent_did: DefId, @@ -805,7 +804,6 @@ fn get_variant( let ctor_did = data.ctor.map(|index| self.local_def_id(index)); ty::VariantDef::new( - tcx, self.item_ident(index, sess), variant_did, ctor_did, @@ -826,6 +824,7 @@ fn get_variant( adt_kind, parent_did, false, + data.is_non_exhaustive, ) } @@ -847,10 +846,10 @@ fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef .get(self, item_id) .unwrap_or(Lazy::empty()) .decode(self) - .map(|index| self.get_variant(tcx, &self.kind(index), index, did, tcx.sess)) + .map(|index| self.get_variant(&self.kind(index), index, did, tcx.sess)) .collect() } else { - std::iter::once(self.get_variant(tcx, &kind, item_id, did, tcx.sess)).collect() + std::iter::once(self.get_variant(&kind, item_id, did, tcx.sess)).collect() }; tcx.alloc_adt_def(did, adt_kind, variants, repr) diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index dc8d14a44f8..49aaa845bc2 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -738,6 +738,7 @@ fn encode_enum_variant_info(&mut self, def: &ty::AdtDef, index: VariantIdx) { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: variant.ctor_def_id.map(|did| did.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; let enum_id = tcx.hir().as_local_hir_id(def.did.expect_local()); @@ -782,6 +783,7 @@ fn encode_enum_variant_ctor(&mut self, def: &ty::AdtDef, index: VariantIdx) { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; // Variant constructors have the same visibility as the parent enums, unless marked as @@ -886,6 +888,7 @@ fn encode_struct_ctor(&mut self, adt_def: &ty::AdtDef, def_id: DefId) { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; let struct_id = tcx.hir().as_local_hir_id(adt_def.did.expect_local()); @@ -1235,6 +1238,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }), adt_def.repr) } hir::ItemKind::Union(..) => { @@ -1245,6 +1249,7 @@ fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: None, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), }), adt_def.repr) } hir::ItemKind::Impl { defaultness, .. } => { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 55ef66f1939..1837b86f4b5 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -346,6 +346,7 @@ struct VariantData { discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. ctor: Option, + is_non_exhaustive: bool, } #[derive(RustcEncodable, RustcDecodable)] diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index d1c6d3be5f4..6e77aab2777 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -2046,7 +2046,6 @@ impl<'tcx> VariantDef { /// If someone speeds up attribute loading to not be a performance concern, they can /// remove this hack and use the constructor `DefId` everywhere. pub fn new( - tcx: TyCtxt<'tcx>, ident: Ident, variant_did: Option, ctor_def_id: Option, @@ -2056,6 +2055,7 @@ pub fn new( adt_kind: AdtKind, parent_did: DefId, recovered: bool, + is_field_list_non_exhaustive: bool, ) -> Self { debug!( "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, @@ -2064,14 +2064,8 @@ pub fn new( ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; - if adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) { - debug!("found non-exhaustive field list for {:?}", parent_did); - flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; - } else if let Some(variant_did) = variant_did { - if tcx.has_attr(variant_did, sym::non_exhaustive) { - debug!("found non-exhaustive field list for {:?}", variant_did); - flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; - } + if is_field_list_non_exhaustive { + flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } VariantDef { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 76439af79f3..8715dacb324 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -858,7 +858,6 @@ fn convert_variant( _ => false, }; ty::VariantDef::new( - tcx, ident, variant_did.map(LocalDefId::to_def_id), ctor_did.map(LocalDefId::to_def_id), @@ -868,6 +867,10 @@ fn convert_variant( adt_kind, parent_did.to_def_id(), recovered, + adt_kind == AdtKind::Struct && tcx.has_attr(parent_did.to_def_id(), sym::non_exhaustive) + || variant_did.map_or(false, |variant_did| { + tcx.has_attr(variant_did.to_def_id(), sym::non_exhaustive) + }), ) }