}
}
- ty::Tuple(tys) => {
- if let Some((&last_ty, _)) = tys.split_last() {
- ty = last_ty.expect_ty();
- } else {
- break;
- }
+ ty::Tuple(tys) if let Some((&last_ty, _)) = tys.split_last() => {
+ ty = last_ty.expect_ty();
}
+ ty::Tuple(_) => break,
+
ty::Projection(_) | ty::Opaque(..) => {
let normalized = normalize(ty);
if ty == normalized {
expanded_cache: FxHashMap::default(),
primary_def_id: Some(def_id),
found_recursion: false,
+ found_any_recursion: false,
check_recursion: true,
tcx: self,
};
expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>,
primary_def_id: Option<DefId>,
found_recursion: bool,
+ found_any_recursion: bool,
/// Whether or not to check for recursive opaque types.
/// This is `true` when we're explicitly checking for opaque type
/// recursion, and 'false' otherwise to avoid unnecessary work.
impl<'tcx> OpaqueTypeExpander<'tcx> {
fn expand_opaque_ty(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) -> Option<Ty<'tcx>> {
- if self.found_recursion {
+ if self.found_any_recursion {
return None;
}
let substs = substs.fold_with(self);
} else {
// If another opaque type that we contain is recursive, then it
// will report the error, so we don't have to.
+ self.found_any_recursion = true;
self.found_recursion = def_id == *self.primary_def_id.as_ref().unwrap();
None
}
}
/// Checks whether values of this type `T` implement the `Freeze`
- /// trait -- frozen types are those that do not contain a
+ /// trait -- frozen types are those that do not contain an
/// `UnsafeCell` anywhere. This is a language concept used to
/// distinguish "true immutability", which is relevant to
/// optimization as well as the rules around static values. Note
expanded_cache: FxHashMap::default(),
primary_def_id: None,
found_recursion: false,
+ found_any_recursion: false,
check_recursion: false,
tcx,
};