]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_infer/src/infer/mod.rs
Rollup merge of #99618 - compiler-errors:uhh-idk, r=lcnr
[rust.git] / compiler / rustc_infer / src / infer / mod.rs
index 4595cf6e270d22f01d93c2a308f938b206f6e603..260b1affda9f855ff0015360b7141503cf59ca0a 100644 (file)
@@ -405,15 +405,7 @@ pub enum SubregionOrigin<'tcx> {
 
     /// Comparing the signature and requirements of an impl method against
     /// the containing trait.
-    CompareImplMethodObligation {
-        span: Span,
-        impl_item_def_id: LocalDefId,
-        trait_item_def_id: DefId,
-    },
-
-    /// Comparing the signature and requirements of an impl associated type
-    /// against the containing trait
-    CompareImplTypeObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
+    CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
 
     /// Checking that the bounds of a trait's associated type hold for a given impl
     CheckAssociatedTypeBounds {
@@ -1701,33 +1693,7 @@ pub fn const_eval_resolve(
                 }
                 Ok(Some(ct)) => {
                     if ct.unify_failure_kind(self.tcx) == FailureKind::Concrete {
-                        substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
-                            let needs_replacement =
-                                arg.has_param_types_or_consts() || arg.has_infer_types_or_consts();
-                            match arg.unpack() {
-                                GenericArgKind::Type(_) if needs_replacement => self
-                                    .tcx
-                                    .mk_ty(ty::Placeholder(ty::PlaceholderType {
-                                        universe: ty::UniverseIndex::ROOT,
-                                        name: ty::BoundVar::from_usize(idx),
-                                    }))
-                                    .into(),
-                                GenericArgKind::Const(ct) if needs_replacement => self
-                                    .tcx
-                                    .mk_const(ty::ConstS {
-                                        ty: ct.ty(),
-                                        kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
-                                            universe: ty::UniverseIndex::ROOT,
-                                            name: ty::BoundConst {
-                                                var: ty::BoundVar::from_usize(idx),
-                                                ty: ct.ty(),
-                                            },
-                                        }),
-                                    })
-                                    .into(),
-                                _ => arg,
-                            }
-                        }));
+                        substs = replace_param_and_infer_substs_with_placeholder(self.tcx, substs);
                     } else {
                         return Err(ErrorHandled::TooGeneric);
                     }
@@ -1980,8 +1946,7 @@ pub fn span(&self) -> Span {
             ReborrowUpvar(a, _) => a,
             DataBorrowed(_, a) => a,
             ReferenceOutlivesReferent(_, a) => a,
-            CompareImplMethodObligation { span, .. } => span,
-            CompareImplTypeObligation { span, .. } => span,
+            CompareImplItemObligation { span, .. } => span,
             CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
         }
     }
@@ -1995,19 +1960,11 @@ pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default:
                 SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
             }
 
-            traits::ObligationCauseCode::CompareImplMethodObligation {
-                impl_item_def_id,
-                trait_item_def_id,
-            } => SubregionOrigin::CompareImplMethodObligation {
-                span: cause.span,
-                impl_item_def_id,
-                trait_item_def_id,
-            },
-
-            traits::ObligationCauseCode::CompareImplTypeObligation {
+            traits::ObligationCauseCode::CompareImplItemObligation {
                 impl_item_def_id,
                 trait_item_def_id,
-            } => SubregionOrigin::CompareImplTypeObligation {
+                kind: _,
+            } => SubregionOrigin::CompareImplItemObligation {
                 span: cause.span,
                 impl_item_def_id,
                 trait_item_def_id,
@@ -2052,3 +2009,43 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         )
     }
 }
+
+/// Replaces substs that reference param or infer variables with suitable
+/// placeholders. This function is meant to remove these param and infer
+/// substs when they're not actually needed to evaluate a constant.
+fn replace_param_and_infer_substs_with_placeholder<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    substs: SubstsRef<'tcx>,
+) -> SubstsRef<'tcx> {
+    tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
+        match arg.unpack() {
+            GenericArgKind::Type(_)
+                if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() =>
+            {
+                tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+                    universe: ty::UniverseIndex::ROOT,
+                    name: ty::BoundVar::from_usize(idx),
+                }))
+                .into()
+            }
+            GenericArgKind::Const(ct)
+                if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() =>
+            {
+                let ty = ct.ty();
+                // If the type references param or infer, replace that too...
+                if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() {
+                    bug!("const `{ct}`'s type should not reference params or types");
+                }
+                tcx.mk_const(ty::ConstS {
+                    ty,
+                    kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
+                        universe: ty::UniverseIndex::ROOT,
+                        name: ty::BoundConst { ty, var: ty::BoundVar::from_usize(idx) },
+                    }),
+                })
+                .into()
+            }
+            _ => arg,
+        }
+    }))
+}