/// bound.
universe: Cell<ty::UniverseIndex>,
- normalize_fn_sig_for_diagnostic:
- Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
-
/// During coherence we have to assume that other crates may add
/// additional impls which we currently don't know about.
///
considering_regions: bool,
/// Whether we are in coherence mode.
intercrate: bool,
- normalize_fn_sig_for_diagnostic:
- Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
}
pub trait TyCtxtInferExt<'tcx> {
tcx: self,
defining_use_anchor: DefiningAnchor::Error,
considering_regions: true,
- normalize_fn_sig_for_diagnostic: None,
intercrate: false,
}
}
self
}
- pub fn with_normalize_fn_sig_for_diagnostic(
- mut self,
- fun: Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
- ) -> Self {
- self.normalize_fn_sig_for_diagnostic = Some(fun);
- self
- }
-
/// Given a canonical value `C` as a starting point, create an
/// inference context that contains each of the bound values
/// within instantiated as a fresh variable. The `f` closure is
}
pub fn build(&mut self) -> InferCtxt<'tcx> {
- let InferCtxtBuilder {
- tcx,
- defining_use_anchor,
- considering_regions,
- ref normalize_fn_sig_for_diagnostic,
- intercrate,
- } = *self;
+ let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
InferCtxt {
tcx,
defining_use_anchor,
in_snapshot: Cell::new(false),
skip_leak_check: Cell::new(false),
universe: Cell::new(ty::UniverseIndex::ROOT),
- normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
- .as_ref()
- .map(|f| f.clone()),
intercrate,
}
}
/// Creates a `TypeErrCtxt` for emitting various inference errors.
/// During typeck, use `FnCtxt::err_ctxt` instead.
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
- TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false }
+ TypeErrCtxt {
+ infcx: self,
+ typeck_results: None,
+ fallback_has_occurred: false,
+ normalize_fn_sig: Box::new(|fn_sig| fn_sig),
+ }
}
pub fn is_in_snapshot(&self) -> bool {
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_non_region_param() || arg.has_non_region_infer() => {
- tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
+ struct ReplaceParamAndInferWithPlaceholder<'tcx> {
+ tcx: TyCtxt<'tcx>,
+ idx: usize,
+ }
+
+ impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+
+ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+ if let ty::Infer(_) = t.kind() {
+ self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::ROOT,
- name: ty::BoundVar::from_usize(idx),
+ name: ty::BoundVar::from_usize({
+ let idx = self.idx;
+ self.idx += 1;
+ idx
+ }),
}))
- .into()
+ } else {
+ t.super_fold_with(self)
}
- GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => {
- let ty = ct.ty();
- // If the type references param or infer, replace that too...
+ }
+
+ fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
+ if let ty::ConstKind::Infer(_) = c.kind() {
+ let ty = c.ty();
+ // If the type references param or infer then ICE ICE ICE
if ty.has_non_region_param() || ty.has_non_region_infer() {
- bug!("const `{ct}`'s type should not reference params or types");
+ bug!("const `{c}`'s type should not reference params or types");
}
- tcx.mk_const(
+ self.tcx.mk_const(
ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT,
- name: ty::BoundVar::from_usize(idx),
+ name: ty::BoundVar::from_usize({
+ let idx = self.idx;
+ self.idx += 1;
+ idx
+ }),
},
ty,
)
- .into()
+ } else {
+ c.super_fold_with(self)
}
- _ => arg,
}
- }))
+ }
+
+ substs.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
}