about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-07-29 04:59:37 +0000
committerbors <bors@rust-lang.org>2020-07-29 04:59:37 +0000
commit10c375700ce170fc57cb617754dc6d0631d3d573 (patch)
tree67d3506998ec9f08305267fac7dbe9e34aaa33d9
parent517385b31b0add8487ff3cc27e216cf3f867ab44 (diff)
parent13ad2322caf3f526d7bff40223c63b684ffe0604 (diff)
downloadrust-10c375700ce170fc57cb617754dc6d0631d3d573.tar.gz
rust-10c375700ce170fc57cb617754dc6d0631d3d573.zip
Auto merge of #74887 - Mark-Simulacrum:cache-non-exhaustive, r=petrochenkov
Cache non-exhaustive separately from attributes

This prevents cross-crate attribute loading from metadata just for non_exhaustive checking; cross-crate attribute loading implies disk reading and is relatively slow.
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs7
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs5
-rw-r--r--src/librustc_metadata/rmeta/mod.rs1
-rw-r--r--src/librustc_middle/ty/mod.rs12
-rw-r--r--src/librustc_typeck/collect.rs5
5 files changed, 16 insertions, 14 deletions
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 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
     fn get_variant(
         &self,
-        tcx: TyCtxt<'tcx>,
         kind: &EntryKind,
         index: DefIndex,
         parent_did: DefId,
@@ -805,7 +804,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         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 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             adt_kind,
             parent_did,
             false,
+            data.is_non_exhaustive,
         )
     }
 
@@ -847,10 +846,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 .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 @@ impl EncodeContext<'a, 'tcx> {
             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 @@ impl EncodeContext<'a, 'tcx> {
             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 @@ impl EncodeContext<'a, 'tcx> {
             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 @@ impl EncodeContext<'a, '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 @@ impl EncodeContext<'a, '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<DefIndex>,
+    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<DefId>,
         ctor_def_id: Option<DefId>,
@@ -2056,6 +2055,7 @@ impl<'tcx> VariantDef {
         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 @@ impl<'tcx> VariantDef {
         );
 
         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)
+            }),
     )
 }