about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs40
1 files changed, 34 insertions, 6 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 80ed72bfaa1..efc353c5c73 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -313,11 +313,12 @@ fn impl_associated_item_for_impl_trait_in_trait(
     trait_assoc_def_id: LocalDefId,
     impl_fn_def_id: LocalDefId,
 ) -> LocalDefId {
-    let impl_def_id = tcx.local_parent(impl_fn_def_id);
+    let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
+    let impl_def_id = impl_local_def_id.to_def_id();
 
     // FIXME fix the span, we probably want the def_id of the return type of the function
     let span = tcx.def_span(impl_fn_def_id);
-    let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy);
+    let impl_assoc_ty = tcx.at(span).create_def(impl_local_def_id, DefPathData::ImplTraitAssocTy);
 
     let local_def_id = impl_assoc_ty.def_id();
     let def_id = local_def_id.to_def_id();
@@ -349,10 +350,37 @@ fn impl_associated_item_for_impl_trait_in_trait(
     // Copy impl_defaultness of the containing function.
     impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id));
 
-    // Copy generics_of the trait's associated item.
-    // FIXME: This is not correct, in particular the parent is going to be wrong. So we would need
-    // to copy from trait_assoc_def_id and adjust things.
-    impl_assoc_ty.generics_of(tcx.generics_of(trait_assoc_def_id).clone());
+    // Copy generics_of the trait's associated item but the impl as the parent.
+    impl_assoc_ty.generics_of({
+        let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
+        let trait_assoc_parent_count = trait_assoc_generics.parent_count;
+        let mut params = trait_assoc_generics.params.clone();
+
+        let parent_generics = tcx.generics_of(impl_def_id);
+        let parent_count = parent_generics.parent_count + parent_generics.params.len();
+
+        let mut impl_fn_params = tcx.generics_of(impl_fn_def_id).params.clone();
+
+        for param in &mut params {
+            param.index = param.index + parent_count as u32 + impl_fn_params.len() as u32
+                - trait_assoc_parent_count as u32;
+        }
+
+        impl_fn_params.extend(params);
+        params = impl_fn_params;
+
+        let param_def_id_to_index =
+            params.iter().map(|param| (param.def_id, param.index)).collect();
+
+        ty::Generics {
+            parent: Some(impl_def_id),
+            parent_count,
+            params,
+            param_def_id_to_index,
+            has_self: false,
+            has_late_bound_regions: trait_assoc_generics.has_late_bound_regions,
+        }
+    });
 
     local_def_id
 }