about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/mod.rs18
-rw-r--r--src/librustc_metadata/decoder.rs8
-rw-r--r--src/librustc_typeck/collect.rs15
3 files changed, 30 insertions, 11 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 940da6099e0..9c91ecca8d9 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1724,19 +1724,29 @@ impl<'a, 'gcx, 'tcx> VariantDef {
     /// - `did` is the DefId used for the variant - for tuple-structs, it is the constructor DefId,
     /// and for everything else, it is the variant DefId.
     /// - `attribute_def_id` is the DefId that has the variant's attributes.
+    /// this is the struct DefId for structs, and the variant DefId for variants.
+    ///
+    /// Note that we *could* use the constructor DefId, because the constructor attributes
+    /// redirect to the base attributes, but compiling a small crate requires
+    /// loading the AdtDefs for all the structs in the universe (e.g. coherence for any
+    /// built-in trait), and we do not want to load attributes twice.
+    ///
+    /// 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<'a, 'gcx, 'tcx>,
                did: DefId,
                name: Name,
                discr: VariantDiscr,
                fields: Vec<FieldDef>,
                adt_kind: AdtKind,
-               ctor_kind: CtorKind)
+               ctor_kind: CtorKind,
+               attribute_def_id: DefId)
                -> Self
     {
-        debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, name, discr, fields,
-               adt_kind, ctor_kind);
+        debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, name, discr,
+               fields, adt_kind, ctor_kind, attribute_def_id);
         let mut flags = VariantFlags::NO_VARIANT_FLAGS;
-        if adt_kind == AdtKind::Struct && tcx.has_attr(did, "non_exhaustive") {
+        if adt_kind == AdtKind::Struct && tcx.has_attr(attribute_def_id, "non_exhaustive") {
             debug!("found non-exhaustive field list for {:?}", did);
             flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
         }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 43b03cb863c..c2296e4f78b 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -556,9 +556,12 @@ impl<'a, 'tcx> CrateMetadata {
             _ => bug!(),
         };
 
+        let def_id = self.local_def_id(data.struct_ctor.unwrap_or(index));
+        let attribute_def_id = self.local_def_id(index);
+
         ty::VariantDef::new(
             tcx,
-            self.local_def_id(data.struct_ctor.unwrap_or(index)),
+            def_id,
             self.item_name(index).as_symbol(),
             data.discr,
             item.children.decode(self).map(|index| {
@@ -570,7 +573,8 @@ impl<'a, 'tcx> CrateMetadata {
                 }
             }).collect(),
             adt_kind,
-            data.ctor_kind
+            data.ctor_kind,
+            attribute_def_id
         )
     }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 5309be21768..7d627e8228a 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -555,7 +555,8 @@ fn convert_variant<'a, 'tcx>(
     name: ast::Name,
     discr: ty::VariantDiscr,
     def: &hir::VariantData,
-    adt_kind: ty::AdtKind
+    adt_kind: ty::AdtKind,
+    attribute_def_id: DefId
 ) -> ty::VariantDef {
     let mut seen_fields: FxHashMap<ast::Ident, Span> = FxHashMap();
     let node_id = tcx.hir.as_local_node_id(did).unwrap();
@@ -592,7 +593,8 @@ fn convert_variant<'a, 'tcx>(
         discr,
         fields,
         adt_kind,
-        CtorKind::from_hir(def))
+        CtorKind::from_hir(def),
+        attribute_def_id)
 }
 
 fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
@@ -622,7 +624,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
                         };
                         distance_from_explicit += 1;
 
-                        convert_variant(tcx, did, v.node.name, discr, &v.node.data, AdtKind::Enum)
+                        convert_variant(tcx, did, v.node.name, discr, &v.node.data, AdtKind::Enum,
+                                        did)
                     })
                     .collect(),
             )
@@ -642,7 +645,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
                     item.name,
                     ty::VariantDiscr::Relative(0),
                     def,
-                    AdtKind::Struct
+                    AdtKind::Struct,
+                    def_id
                 )],
             )
         }
@@ -654,7 +658,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
                 item.name,
                 ty::VariantDiscr::Relative(0),
                 def,
-                AdtKind::Union
+                AdtKind::Union,
+                def_id
             )],
         ),
         _ => bug!(),