Skip to content

Commit

Permalink
Move the peeling function for weak alias types
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Feb 20, 2024
1 parent 1b3df6f commit f515f99
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 28 deletions.
29 changes: 1 addition & 28 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +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);
let self_ty = self.tcx.peel_off_weak_alias_tys(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),
Expand Down Expand Up @@ -186,30 +186,3 @@ 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
}
33 changes: 33 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,39 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn expand_weak_alias_tys<T: TypeFoldable<TyCtxt<'tcx>>>(self, value: T) -> T {
value.fold_with(&mut WeakAliasTypeExpander { tcx: self, depth: 0 })
}

/// Peel off all [weak alias types] in this type until there are none left.
///
/// This only expands weak alias types in “head” / outermost positions. It can
/// be used over [expand_weak_alias_tys] as an optimization in situations where
/// one only really cares about the *kind* of the final aliased type but not
/// the types the other constituent types alias.
///
/// <div class="warning">
/// This delays a bug on overflow! Therefore you need to be certain that the
/// type gets fully normalized at a later stage.
/// </div>
///
/// [weak]: ty::Weak
/// [expand_weak_alias_tys]: Self::expand_weak_alias_tys
pub fn peel_off_weak_alias_tys(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
let ty::Alias(ty::Weak, _) = ty.kind() else { return ty };

let limit = self.recursion_limit();
let mut depth = 0;

while let ty::Alias(ty::Weak, alias) = ty.kind() {
if !limit.value_within_limit(depth) {
let guar = self.dcx().delayed_bug("overflow expanding weak alias type");
return Ty::new_error(self, guar);
}

ty = self.type_of(alias.def_id).instantiate(self, alias.args);
depth += 1;
}

ty
}
}

struct OpaqueTypeExpander<'tcx> {
Expand Down

0 comments on commit f515f99

Please sign in to comment.