about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs13
2 files changed, 13 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 17a4184c3c9..f5a02ee7ad2 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -647,14 +647,14 @@ fn vtable_entries<'tcx>(
                     .filter(|item| item.kind == ty::AssocKind::Fn);
                 // Now list each method's DefId and InternalSubsts (for within its trait).
                 // If the method can never be called from this object, produce `Vacant`.
-                let own_entries = trait_methods.map(move |trait_method| {
+                let own_entries = trait_methods.filter_map(move |trait_method| {
                     debug!("vtable_entries: trait_method={:?}", trait_method);
                     let def_id = trait_method.def_id;
 
                     // Some methods cannot be called on an object; skip those.
                     if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) {
                         debug!("vtable_entries: not vtable safe");
-                        return VtblEntry::Vacant;
+                        return None;
                     }
 
                     // The method may have some early-bound lifetimes; add regions for those.
@@ -681,7 +681,7 @@ fn vtable_entries<'tcx>(
                     let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
                     if impossible_predicates(tcx, predicates.predicates) {
                         debug!("vtable_entries: predicates do not hold");
-                        return VtblEntry::Vacant;
+                        return Some(VtblEntry::Vacant);
                     }
 
                     let instance = ty::Instance::resolve_for_vtable(
@@ -691,7 +691,7 @@ fn vtable_entries<'tcx>(
                         substs,
                     )
                     .expect("resolution failed during building vtable representation");
-                    VtblEntry::Method(instance)
+                    Some(VtblEntry::Method(instance))
                 });
 
                 entries.extend(own_entries);
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index fd94f9f7998..3b98fe48c8c 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -289,7 +289,9 @@ pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'
     // Count number of methods and add them to the total offset.
     // Skip over associated types and constants.
     for trait_item in tcx.associated_items(trait_ref.def_id()).in_definition_order() {
-        if trait_item.kind == ty::AssocKind::Fn {
+        let is_vtable_safe_method = trait_item.kind == ty::AssocKind::Fn
+            && super::is_vtable_safe_method(tcx, trait_ref.def_id(), trait_item);
+        if is_vtable_safe_method {
             entries += 1;
         }
     }
@@ -308,13 +310,16 @@ pub fn get_vtable_index_of_object_method<N>(
     // add them to the total offset.
     // Skip over associated types and constants, as those aren't stored in the vtable.
     let mut entries = object.vtable_base;
-    for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()).in_definition_order() {
+    let trait_def_id = object.upcast_trait_ref.def_id();
+    for trait_item in tcx.associated_items(trait_def_id).in_definition_order() {
+        let is_vtable_safe_method = trait_item.kind == ty::AssocKind::Fn
+            && super::is_vtable_safe_method(tcx, trait_def_id, trait_item);
         if trait_item.def_id == method_def_id {
             // The item with the ID we were given really ought to be a method.
-            assert_eq!(trait_item.kind, ty::AssocKind::Fn);
+            assert!(is_vtable_safe_method);
             return entries;
         }
-        if trait_item.kind == ty::AssocKind::Fn {
+        if is_vtable_safe_method {
             entries += 1;
         }
     }