diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 0df5a57bc2c..4823472cf96 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -144,6 +144,7 @@ impl<'tcx> InherentCollect<'tcx> { let id = id.owner_id.def_id; let item_span = self.tcx.def_span(id); let self_ty = self.tcx.type_of(id).instantiate_identity(); + let self_ty = peel_off_weak_aliases(self.tcx, self_ty); match *self_ty.kind() { ty::Adt(def, _) => self.check_def_id(id, self_ty, def.did()), ty::Foreign(did) => self.check_def_id(id, self_ty, did), @@ -166,7 +167,7 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Never | ty::FnPtr(_) | ty::Tuple(..) => self.check_primitive_impl(id, self_ty), - ty::Alias(..) | ty::Param(_) => { + ty::Alias(ty::Projection | ty::Inherent | ty::Opaque, _) | ty::Param(_) => { Err(self.tcx.dcx().emit_err(errors::InherentNominal { span: item_span })) } ty::FnDef(..) @@ -174,6 +175,7 @@ impl<'tcx> InherentCollect<'tcx> { | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) + | ty::Alias(ty::Weak, _) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => { @@ -184,3 +186,30 @@ impl<'tcx> InherentCollect<'tcx> { } } } + +/// Peel off all weak alias types in this type until there are none left. +/// +/// <div class="warning"> +/// +/// This assumes that `ty` gets normalized later and that any overflows occurring +/// during said normalization get reported. +/// +/// </div> +fn peel_off_weak_aliases<'tcx>(tcx: TyCtxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> { + let ty::Alias(ty::Weak, _) = ty.kind() else { return ty }; + + let limit = tcx.recursion_limit(); + let mut depth = 0; + + while let ty::Alias(ty::Weak, alias) = ty.kind() { + if !limit.value_within_limit(depth) { + let guar = tcx.dcx().delayed_bug("overflow expanding weak alias type"); + return Ty::new_error(tcx, guar); + } + + ty = tcx.type_of(alias.def_id).instantiate(tcx, alias.args); + depth += 1; + } + + ty +} |
