Rollup merge of #138727 - compiler-errors:ty-var-origin, r=fmease
Do not rely on `type_var_origin` in `OrphanCheckErr::NonLocalInputType` The ordering of ty var unification means that we may end up with a root variable whose ty var origin is from another item's params. Let's not rely on this by just unifying the infer vars with the params of the impl + resolving. It's kinda goofy but it's clearer IMO. Fixes #132826. r? `@fmease` or `@lcnr`
This commit is contained in:
commit
3e04973891
6 changed files with 60 additions and 64 deletions
|
@ -3,11 +3,10 @@
|
|||
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
|
||||
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
|
@ -356,13 +355,20 @@ fn orphan_check<'tcx>(
|
|||
})
|
||||
}
|
||||
OrphanCheckErr::NonLocalInputType(tys) => {
|
||||
let generics = tcx.generics_of(impl_def_id);
|
||||
let tys = tys
|
||||
.into_iter()
|
||||
.map(|(ty, is_target_ty)| {
|
||||
(ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty)
|
||||
})
|
||||
.collect();
|
||||
let tys = infcx.probe(|_| {
|
||||
// Map the unconstrained args back to their params,
|
||||
// ignoring any type unification errors.
|
||||
for (arg, id_arg) in
|
||||
std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id))
|
||||
{
|
||||
let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
arg,
|
||||
id_arg,
|
||||
);
|
||||
}
|
||||
infcx.resolve_vars_if_possible(tys)
|
||||
});
|
||||
OrphanCheckErr::NonLocalInputType(tys)
|
||||
}
|
||||
})
|
||||
|
@ -536,40 +542,3 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TyVarReplacer<'cx, 'tcx> {
|
||||
infcx: &'cx InferCtxt<'tcx>,
|
||||
generics: &'tcx ty::Generics,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
|
||||
return ty;
|
||||
}
|
||||
let ty::Infer(ty::TyVar(vid)) = *ty.kind() else {
|
||||
return ty.super_fold_with(self);
|
||||
};
|
||||
let origin = self.infcx.type_var_origin(vid);
|
||||
if let Some(def_id) = origin.param_def_id {
|
||||
// The generics of an `impl` don't have a parent, we can index directly.
|
||||
let index = self.generics.param_def_id_to_index[&def_id];
|
||||
let name = self.generics.own_params[index as usize].name;
|
||||
|
||||
Ty::new_param(self.infcx.tcx, index, name)
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
|
||||
return ct;
|
||||
}
|
||||
ct.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue