/// 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 {
}
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);
}
ReborrowUpvar(a, _) => a,
DataBorrowed(_, a) => a,
ReferenceOutlivesReferent(_, a) => a,
- CompareImplMethodObligation { span, .. } => span,
- CompareImplTypeObligation { span, .. } => span,
+ CompareImplItemObligation { span, .. } => span,
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
}
}
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,
)
}
}
+
+/// 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,
+ }
+ }))
+}