|
3 | 3 |
|
4 | 4 | use rustc_data_structures::fx::FxIndexSet;
|
5 | 5 | use rustc_errors::ErrorGuaranteed;
|
6 |
| -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; |
| 6 | +use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; |
7 | 7 | use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
|
8 | 8 | use rustc_middle::ty::{
|
9 |
| - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, |
10 |
| - TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, |
| 9 | + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, |
11 | 10 | };
|
12 | 11 | use rustc_middle::{bug, span_bug};
|
13 | 12 | use rustc_span::def_id::{DefId, LocalDefId};
|
@@ -356,13 +355,20 @@ fn orphan_check<'tcx>(
|
356 | 355 | })
|
357 | 356 | }
|
358 | 357 | OrphanCheckErr::NonLocalInputType(tys) => {
|
359 |
| - let generics = tcx.generics_of(impl_def_id); |
360 |
| - let tys = tys |
361 |
| - .into_iter() |
362 |
| - .map(|(ty, is_target_ty)| { |
363 |
| - (ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty) |
364 |
| - }) |
365 |
| - .collect(); |
| 358 | + let tys = infcx.probe(|_| { |
| 359 | + // Map the unconstrained args back to their params, |
| 360 | + // ignoring any type unification errors. |
| 361 | + for (arg, id_arg) in |
| 362 | + std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id)) |
| 363 | + { |
| 364 | + let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq( |
| 365 | + DefineOpaqueTypes::No, |
| 366 | + arg, |
| 367 | + id_arg, |
| 368 | + ); |
| 369 | + } |
| 370 | + infcx.resolve_vars_if_possible(tys) |
| 371 | + }); |
366 | 372 | OrphanCheckErr::NonLocalInputType(tys)
|
367 | 373 | }
|
368 | 374 | })
|
@@ -536,40 +542,3 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
|
536 | 542 | }
|
537 | 543 | }
|
538 | 544 | }
|
539 |
| - |
540 |
| -struct TyVarReplacer<'cx, 'tcx> { |
541 |
| - infcx: &'cx InferCtxt<'tcx>, |
542 |
| - generics: &'tcx ty::Generics, |
543 |
| -} |
544 |
| - |
545 |
| -impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> { |
546 |
| - fn cx(&self) -> TyCtxt<'tcx> { |
547 |
| - self.infcx.tcx |
548 |
| - } |
549 |
| - |
550 |
| - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { |
551 |
| - if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { |
552 |
| - return ty; |
553 |
| - } |
554 |
| - let ty::Infer(ty::TyVar(vid)) = *ty.kind() else { |
555 |
| - return ty.super_fold_with(self); |
556 |
| - }; |
557 |
| - let origin = self.infcx.type_var_origin(vid); |
558 |
| - if let Some(def_id) = origin.param_def_id { |
559 |
| - // The generics of an `impl` don't have a parent, we can index directly. |
560 |
| - let index = self.generics.param_def_id_to_index[&def_id]; |
561 |
| - let name = self.generics.own_params[index as usize].name; |
562 |
| - |
563 |
| - Ty::new_param(self.infcx.tcx, index, name) |
564 |
| - } else { |
565 |
| - ty |
566 |
| - } |
567 |
| - } |
568 |
| - |
569 |
| - fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { |
570 |
| - if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) { |
571 |
| - return ct; |
572 |
| - } |
573 |
| - ct.super_fold_with(self) |
574 |
| - } |
575 |
| -} |
0 commit comments