about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2023-03-14 14:29:06 -0300
committerSantiago Pastorino <spastorino@gmail.com>2023-03-15 12:27:16 -0300
commit39ffe9699a2b24c72bebd1c952daf31707b68106 (patch)
tree9757f6351eb5de8526969fe513c4aa40a7e95458
parent26c4c1ea97d16863dbbaf2688d5dc7ce1ca3680b (diff)
downloadrust-39ffe9699a2b24c72bebd1c952daf31707b68106.tar.gz
rust-39ffe9699a2b24c72bebd1c952daf31707b68106.zip
Properly implement generics_of for traits
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index aba8f49b691..fae5997e394 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -289,8 +289,37 @@ fn associated_item_for_impl_trait_in_trait(
         InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()),
     )));
 
-    // Copy generics_of of the opaque.
-    trait_assoc_ty.generics_of(tcx.generics_of(opaque_ty_def_id).clone());
+    // Copy generics_of of the opaque type item but the trait is the parent.
+    trait_assoc_ty.generics_of({
+        let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id);
+        let opaque_ty_parent_count = opaque_ty_generics.parent_count;
+        let mut params = opaque_ty_generics.params.clone();
+
+        let parent_generics = tcx.generics_of(trait_def_id);
+        let parent_count = parent_generics.parent_count + parent_generics.params.len();
+
+        let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
+
+        for param in &mut params {
+            param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
+                - opaque_ty_parent_count as u32;
+        }
+
+        trait_fn_params.extend(params);
+        params = trait_fn_params;
+
+        let param_def_id_to_index =
+            params.iter().map(|param| (param.def_id, param.index)).collect();
+
+        ty::Generics {
+            parent: Some(trait_def_id),
+            parent_count,
+            params,
+            param_def_id_to_index,
+            has_self: false,
+            has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
+        }
+    });
 
     // There are no predicates for the synthesized associated type.
     trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {