Better handling for exponential-sized types in misc places
Mostly to fix ui/issues/issue-37311-type-length-limit/issue-37311.rs. Most parts of the compiler can handle deeply nested types with a lot of duplicates just fine, but some parts still attempt to naively traverse type tree. Before such problems were caught by type length limit check, but now these places will have to be changed to handle duplicated types gracefully.
This commit is contained in:
parent
2f3296192b
commit
17d2e3b5d2
12 changed files with 91 additions and 43 deletions
|
@ -4,6 +4,7 @@ use crate::ty::{self, DefIdTree, Ty, TyCtxt};
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::ty::walk::MiniSet;
|
||||
|
||||
// `pretty` is a separate module only for organization.
|
||||
mod pretty;
|
||||
|
@ -263,22 +264,34 @@ pub trait Printer<'tcx>: Sized {
|
|||
/// function tries to find a "characteristic `DefId`" for a
|
||||
/// type. It's just a heuristic so it makes some questionable
|
||||
/// decisions and we may want to adjust it later.
|
||||
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
||||
///
|
||||
/// Visited set is needed in to avoid full iteration over
|
||||
/// deeply nested tuples that have no DefId.
|
||||
fn characteristic_def_id_of_type_cached<'a>(
|
||||
ty: Ty<'a>,
|
||||
visited: &mut MiniSet<Ty<'a>>,
|
||||
) -> Option<DefId> {
|
||||
match *ty.kind() {
|
||||
ty::Adt(adt_def, _) => Some(adt_def.did),
|
||||
|
||||
ty::Dynamic(data, ..) => data.principal_def_id(),
|
||||
|
||||
ty::Array(subty, _) | ty::Slice(subty) => characteristic_def_id_of_type(subty),
|
||||
|
||||
ty::RawPtr(mt) => characteristic_def_id_of_type(mt.ty),
|
||||
|
||||
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
|
||||
|
||||
ty::Tuple(ref tys) => {
|
||||
tys.iter().find_map(|ty| characteristic_def_id_of_type(ty.expect_ty()))
|
||||
ty::Array(subty, _) | ty::Slice(subty) => {
|
||||
characteristic_def_id_of_type_cached(subty, visited)
|
||||
}
|
||||
|
||||
ty::RawPtr(mt) => characteristic_def_id_of_type_cached(mt.ty, visited),
|
||||
|
||||
ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited),
|
||||
|
||||
ty::Tuple(ref tys) => tys.iter().find_map(|ty| {
|
||||
let ty = ty.expect_ty();
|
||||
if visited.insert(ty) {
|
||||
return characteristic_def_id_of_type_cached(ty, visited);
|
||||
}
|
||||
return None;
|
||||
}),
|
||||
|
||||
ty::FnDef(def_id, _)
|
||||
| ty::Closure(def_id, _)
|
||||
| ty::Generator(def_id, _, _)
|
||||
|
@ -302,6 +315,9 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
|||
| ty::Float(_) => None,
|
||||
}
|
||||
}
|
||||
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
||||
characteristic_def_id_of_type_cached(ty, &mut MiniSet::new())
|
||||
}
|
||||
|
||||
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
|
||||
type Output = P::Region;
|
||||
|
|
|
@ -1264,6 +1264,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
|
|||
used_region_names: FxHashSet<Symbol>,
|
||||
region_index: usize,
|
||||
binder_depth: usize,
|
||||
printed_type_count: usize,
|
||||
|
||||
pub region_highlight_mode: RegionHighlightMode,
|
||||
|
||||
|
@ -1294,6 +1295,7 @@ impl<F> FmtPrinter<'a, 'tcx, F> {
|
|||
used_region_names: Default::default(),
|
||||
region_index: 0,
|
||||
binder_depth: 0,
|
||||
printed_type_count: 0,
|
||||
region_highlight_mode: RegionHighlightMode::default(),
|
||||
name_resolver: None,
|
||||
}))
|
||||
|
@ -1411,8 +1413,14 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
|||
self.pretty_print_region(region)
|
||||
}
|
||||
|
||||
fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
|
||||
self.pretty_print_type(ty)
|
||||
fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
|
||||
if self.tcx.sess.type_length_limit().value_within_limit(self.printed_type_count) {
|
||||
self.printed_type_count += 1;
|
||||
self.pretty_print_type(ty)
|
||||
} else {
|
||||
write!(self, "...")?;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_dyn_existential(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue