2024-05-24 18:09:40 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
2024-05-10 18:59:56 +00:00
|
|
|
use hir::def::Namespace;
|
2018-12-04 17:13:37 +00:00
|
|
|
use rustc_data_structures::fx::FxHashSet;
|
2020-09-24 04:32:11 +00:00
|
|
|
use rustc_data_structures::sso::SsoHashSet;
|
2024-01-29 17:41:51 +00:00
|
|
|
use rustc_hir as hir;
|
2022-10-10 18:03:19 +00:00
|
|
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
2020-03-24 08:09:42 +00:00
|
|
|
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
2024-05-22 05:20:21 +00:00
|
|
|
use tracing::{debug, instrument, trace};
|
2018-12-04 17:13:37 +00:00
|
|
|
|
2024-05-24 18:09:40 +00:00
|
|
|
use crate::ty::{self, GenericArg, ShortInstance, Ty, TyCtxt};
|
2024-07-28 22:13:50 +00:00
|
|
|
|
2019-01-18 19:33:31 +00:00
|
|
|
// `pretty` is a separate module only for organization.
|
|
|
|
mod pretty;
|
|
|
|
pub use self::pretty::*;
|
2024-05-10 18:59:56 +00:00
|
|
|
use super::Lift;
|
|
|
|
|
2023-10-16 18:46:24 +00:00
|
|
|
pub type PrintError = std::fmt::Error;
|
|
|
|
|
2019-06-13 21:48:52 +00:00
|
|
|
pub trait Print<'tcx, P> {
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print(&self, cx: &mut P) -> Result<(), PrintError>;
|
2018-12-04 17:13:37 +00:00
|
|
|
}
|
2018-12-10 14:10:22 +00:00
|
|
|
|
2019-03-14 17:47:24 +00:00
|
|
|
/// Interface for outputting user-facing "type-system entities"
|
|
|
|
/// (paths, types, lifetimes, constants, etc.) as a side-effect
|
|
|
|
/// (e.g. formatting, like `PrettyPrinter` implementors do) or by
|
|
|
|
/// constructing some alternative representation (e.g. an AST),
|
|
|
|
/// which the associated types allow passing through the methods.
|
|
|
|
///
|
|
|
|
/// For pretty-printing/formatting in particular, see `PrettyPrinter`.
|
2019-09-06 02:57:44 +00:00
|
|
|
//
|
|
|
|
// FIXME(eddyb) find a better name; this is more general than "printing".
|
2019-06-13 21:48:52 +00:00
|
|
|
pub trait Printer<'tcx>: Sized {
|
2021-12-16 00:32:30 +00:00
|
|
|
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
2019-01-25 10:11:50 +00:00
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
fn print_def_path(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2018-12-19 11:25:31 +00:00
|
|
|
def_id: DefId,
|
2023-07-11 21:35:29 +00:00
|
|
|
args: &'tcx [GenericArg<'tcx>],
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError> {
|
2023-07-11 21:35:29 +00:00
|
|
|
self.default_print_def_path(def_id, args)
|
2018-12-19 11:25:31 +00:00
|
|
|
}
|
2019-09-06 02:57:44 +00:00
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
fn print_impl_path(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2018-12-19 11:25:31 +00:00
|
|
|
impl_def_id: DefId,
|
2023-07-11 21:35:29 +00:00
|
|
|
args: &'tcx [GenericArg<'tcx>],
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError> {
|
2025-01-06 06:10:36 +00:00
|
|
|
let tcx = self.tcx();
|
|
|
|
let self_ty = tcx.type_of(impl_def_id);
|
|
|
|
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
|
|
|
|
let (self_ty, impl_trait_ref) = if tcx.generics_of(impl_def_id).count() <= args.len() {
|
|
|
|
(
|
|
|
|
self_ty.instantiate(tcx, args),
|
|
|
|
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate(tcx, args)),
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
// We are probably printing a nested item inside of an impl.
|
|
|
|
// Use the identity substitutions for the impl.
|
|
|
|
(
|
|
|
|
self_ty.instantiate_identity(),
|
|
|
|
impl_trait_ref.map(|impl_trait_ref| impl_trait_ref.instantiate_identity()),
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
|
|
|
self.default_print_impl_path(impl_def_id, self_ty, impl_trait_ref)
|
2018-12-19 11:25:31 +00:00
|
|
|
}
|
|
|
|
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print_region(&mut self, region: ty::Region<'tcx>) -> Result<(), PrintError>;
|
2019-01-14 15:55:57 +00:00
|
|
|
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError>;
|
2019-01-14 17:56:46 +00:00
|
|
|
|
2019-01-24 18:47:02 +00:00
|
|
|
fn print_dyn_existential(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2022-11-19 03:28:56 +00:00
|
|
|
predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError>;
|
2019-01-24 18:47:02 +00:00
|
|
|
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError>;
|
2019-03-18 10:50:57 +00:00
|
|
|
|
2023-10-17 17:46:14 +00:00
|
|
|
fn path_crate(&mut self, cnum: CrateNum) -> Result<(), PrintError>;
|
2019-09-06 02:57:44 +00:00
|
|
|
|
2018-12-21 15:10:21 +00:00
|
|
|
fn path_qualified(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2018-12-21 15:10:21 +00:00
|
|
|
self_ty: Ty<'tcx>,
|
|
|
|
trait_ref: Option<ty::TraitRef<'tcx>>,
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError>;
|
2019-01-10 11:27:11 +00:00
|
|
|
|
2019-01-25 10:11:50 +00:00
|
|
|
fn path_append_impl(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
|
|
|
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
2019-02-03 10:59:37 +00:00
|
|
|
disambiguated_data: &DisambiguatedDefPathData,
|
2019-01-10 11:27:11 +00:00
|
|
|
self_ty: Ty<'tcx>,
|
|
|
|
trait_ref: Option<ty::TraitRef<'tcx>>,
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError>;
|
2019-09-06 02:57:44 +00:00
|
|
|
|
2019-01-25 10:11:50 +00:00
|
|
|
fn path_append(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
|
|
|
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
2019-02-03 10:59:37 +00:00
|
|
|
disambiguated_data: &DisambiguatedDefPathData,
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError>;
|
2019-09-06 02:57:44 +00:00
|
|
|
|
2019-01-25 10:11:50 +00:00
|
|
|
fn path_generic_args(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
|
|
|
print_prefix: impl FnOnce(&mut Self) -> Result<(), PrintError>,
|
2019-09-25 15:39:44 +00:00
|
|
|
args: &[GenericArg<'tcx>],
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError>;
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2025-01-31 03:26:56 +00:00
|
|
|
fn should_truncate(&mut self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2020-03-06 11:13:55 +00:00
|
|
|
// Defaults (should not be overridden):
|
2019-01-25 10:11:50 +00:00
|
|
|
|
2022-06-02 17:42:29 +00:00
|
|
|
#[instrument(skip(self), level = "debug")]
|
2019-01-25 10:11:50 +00:00
|
|
|
fn default_print_def_path(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2018-12-19 11:25:31 +00:00
|
|
|
def_id: DefId,
|
2023-07-11 21:35:29 +00:00
|
|
|
args: &'tcx [GenericArg<'tcx>],
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError> {
|
2019-01-25 10:11:50 +00:00
|
|
|
let key = self.tcx().def_key(def_id);
|
2021-08-20 13:36:04 +00:00
|
|
|
debug!(?key);
|
2018-12-21 15:10:21 +00:00
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
match key.disambiguated_data.data {
|
|
|
|
DefPathData::CrateRoot => {
|
|
|
|
assert!(key.parent.is_none());
|
|
|
|
self.path_crate(def_id.krate)
|
|
|
|
}
|
|
|
|
|
2025-01-06 06:10:36 +00:00
|
|
|
DefPathData::Impl => self.print_impl_path(def_id, args),
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2018-12-21 15:10:21 +00:00
|
|
|
_ => {
|
|
|
|
let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
|
2019-01-29 05:21:11 +00:00
|
|
|
|
2023-07-11 21:35:29 +00:00
|
|
|
let mut parent_args = args;
|
2019-01-29 05:21:11 +00:00
|
|
|
let mut trait_qualify_parent = false;
|
2023-07-11 21:35:29 +00:00
|
|
|
if !args.is_empty() {
|
2019-01-29 05:21:11 +00:00
|
|
|
let generics = self.tcx().generics_of(def_id);
|
2023-07-11 21:35:29 +00:00
|
|
|
parent_args = &args[..generics.parent_count.min(args.len())];
|
2019-01-29 05:21:11 +00:00
|
|
|
|
2019-01-10 11:27:11 +00:00
|
|
|
match key.disambiguated_data.data {
|
2024-01-29 17:41:51 +00:00
|
|
|
DefPathData::Closure => {
|
2025-03-30 21:39:12 +00:00
|
|
|
// We need to additionally print the `kind` field of a coroutine if
|
2024-01-29 17:41:51 +00:00
|
|
|
// it is desugared from a coroutine-closure.
|
|
|
|
if let Some(hir::CoroutineKind::Desugared(
|
|
|
|
_,
|
|
|
|
hir::CoroutineSource::Closure,
|
|
|
|
)) = self.tcx().coroutine_kind(def_id)
|
2024-02-23 18:56:35 +00:00
|
|
|
&& args.len() > parent_args.len()
|
2024-01-29 17:41:51 +00:00
|
|
|
{
|
|
|
|
return self.path_generic_args(
|
|
|
|
|cx| cx.print_def_path(def_id, parent_args),
|
|
|
|
&args[..parent_args.len() + 1][..1],
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
// Closures' own generics are only captures, don't print them.
|
|
|
|
}
|
|
|
|
}
|
2025-03-30 21:39:12 +00:00
|
|
|
DefPathData::SyntheticCoroutineBody => {
|
|
|
|
// Synthetic coroutine bodies have no distinct generics, since like
|
|
|
|
// closures they're all just internal state of the coroutine.
|
|
|
|
}
|
2022-04-29 14:27:05 +00:00
|
|
|
// This covers both `DefKind::AnonConst` and `DefKind::InlineConst`.
|
|
|
|
// Anon consts doesn't have their own generics, and inline consts' own
|
|
|
|
// generics are their inferred types, so don't print them.
|
|
|
|
DefPathData::AnonConst => {}
|
2019-01-29 05:21:11 +00:00
|
|
|
|
|
|
|
// If we have any generic arguments to print, we do that
|
|
|
|
// on top of the same path, but without its own generics.
|
|
|
|
_ => {
|
2024-05-11 09:46:25 +00:00
|
|
|
if !generics.is_own_empty() && args.len() >= generics.count() {
|
2023-12-10 10:17:28 +00:00
|
|
|
let args = generics.own_args_no_defaults(self.tcx(), args);
|
2019-01-29 05:21:11 +00:00
|
|
|
return self.path_generic_args(
|
2023-07-11 21:35:29 +00:00
|
|
|
|cx| cx.print_def_path(def_id, parent_args),
|
2019-01-29 05:21:11 +00:00
|
|
|
args,
|
|
|
|
);
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2019-01-10 11:27:11 +00:00
|
|
|
}
|
2018-12-21 15:10:21 +00:00
|
|
|
}
|
|
|
|
|
2019-01-29 05:21:11 +00:00
|
|
|
// FIXME(eddyb) try to move this into the parent's printing
|
|
|
|
// logic, instead of doing it when printing the child.
|
|
|
|
trait_qualify_parent = generics.has_self
|
|
|
|
&& generics.parent == Some(parent_def_id)
|
2023-07-11 21:35:29 +00:00
|
|
|
&& parent_args.len() == generics.parent_count
|
2019-01-29 05:21:11 +00:00
|
|
|
&& self.tcx().generics_of(parent_def_id).parent_count == 0;
|
2018-12-21 15:10:21 +00:00
|
|
|
}
|
2019-01-29 05:21:11 +00:00
|
|
|
|
|
|
|
self.path_append(
|
2023-10-17 17:46:14 +00:00
|
|
|
|cx: &mut Self| {
|
2019-01-29 05:21:11 +00:00
|
|
|
if trait_qualify_parent {
|
2023-04-25 16:07:48 +00:00
|
|
|
let trait_ref = ty::TraitRef::new(
|
|
|
|
cx.tcx(),
|
|
|
|
parent_def_id,
|
2023-07-11 21:35:29 +00:00
|
|
|
parent_args.iter().copied(),
|
2023-04-25 16:07:48 +00:00
|
|
|
);
|
2019-01-29 05:21:11 +00:00
|
|
|
cx.path_qualified(trait_ref.self_ty(), Some(trait_ref))
|
|
|
|
} else {
|
2023-07-11 21:35:29 +00:00
|
|
|
cx.print_def_path(parent_def_id, parent_args)
|
2019-12-22 22:42:04 +00:00
|
|
|
}
|
2019-01-29 05:21:11 +00:00
|
|
|
},
|
2019-02-03 10:59:37 +00:00
|
|
|
&key.disambiguated_data,
|
2019-01-29 05:21:11 +00:00
|
|
|
)
|
2018-12-19 11:25:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default_print_impl_path(
|
2023-10-17 17:46:14 +00:00
|
|
|
&mut self,
|
2018-12-19 11:25:31 +00:00
|
|
|
impl_def_id: DefId,
|
2018-12-21 18:08:01 +00:00
|
|
|
self_ty: Ty<'tcx>,
|
|
|
|
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
2023-10-17 17:46:14 +00:00
|
|
|
) -> Result<(), PrintError> {
|
2018-12-21 18:08:01 +00:00
|
|
|
debug!(
|
|
|
|
"default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
|
|
|
|
impl_def_id, self_ty, impl_trait_ref
|
|
|
|
);
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2019-02-03 10:59:37 +00:00
|
|
|
let key = self.tcx().def_key(impl_def_id);
|
|
|
|
let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
|
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
// Decide whether to print the parent path for the impl.
|
|
|
|
// Logically, since impls are global, it's never needed, but
|
|
|
|
// users may find it useful. Currently, we omit the parent if
|
|
|
|
// the impl is either in the same module as the self-type or
|
|
|
|
// as the trait.
|
|
|
|
let in_self_mod = match characteristic_def_id_of_type(self_ty) {
|
|
|
|
None => false,
|
2022-04-25 19:08:45 +00:00
|
|
|
Some(ty_def_id) => self.tcx().parent(ty_def_id) == parent_def_id,
|
2018-12-19 11:25:31 +00:00
|
|
|
};
|
|
|
|
let in_trait_mod = match impl_trait_ref {
|
|
|
|
None => false,
|
2022-04-25 19:08:45 +00:00
|
|
|
Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == parent_def_id,
|
2018-12-19 11:25:31 +00:00
|
|
|
};
|
|
|
|
|
2019-01-10 11:27:11 +00:00
|
|
|
if !in_self_mod && !in_trait_mod {
|
2018-12-19 11:25:31 +00:00
|
|
|
// If the impl is not co-located with either self-type or
|
|
|
|
// trait-type, then fallback to a format that identifies
|
|
|
|
// the module more clearly.
|
2019-01-10 11:27:11 +00:00
|
|
|
self.path_append_impl(
|
2019-01-29 05:21:11 +00:00
|
|
|
|cx| cx.print_def_path(parent_def_id, &[]),
|
2019-02-03 10:59:37 +00:00
|
|
|
&key.disambiguated_data,
|
2019-01-10 11:27:11 +00:00
|
|
|
self_ty,
|
|
|
|
impl_trait_ref,
|
|
|
|
)
|
2018-12-28 04:09:22 +00:00
|
|
|
} else {
|
|
|
|
// Otherwise, try to give a good form that would be valid language
|
|
|
|
// syntax. Preferably using associated item notation.
|
2019-01-14 21:40:53 +00:00
|
|
|
self.path_qualified(self_ty, impl_trait_ref)
|
2019-01-10 11:27:11 +00:00
|
|
|
}
|
2018-12-19 11:25:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// As a heuristic, when we see an impl, if we see that the
|
|
|
|
/// 'self type' is a type defined in the same module as the impl,
|
|
|
|
/// we can omit including the path to the impl itself. This
|
|
|
|
/// 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.
|
2020-09-15 23:22:24 +00:00
|
|
|
///
|
2020-09-18 06:07:19 +00:00
|
|
|
/// Visited set is needed to avoid full iteration over
|
2020-09-15 23:22:24 +00:00
|
|
|
/// deeply nested tuples that have no DefId.
|
|
|
|
fn characteristic_def_id_of_type_cached<'a>(
|
|
|
|
ty: Ty<'a>,
|
2020-09-24 04:32:11 +00:00
|
|
|
visited: &mut SsoHashSet<Ty<'a>>,
|
2020-09-15 23:22:24 +00:00
|
|
|
) -> Option<DefId> {
|
2020-08-02 22:49:11 +00:00
|
|
|
match *ty.kind() {
|
2022-03-04 20:28:41 +00:00
|
|
|
ty::Adt(adt_def, _) => Some(adt_def.did()),
|
2018-12-19 11:25:31 +00:00
|
|
|
|
|
|
|
ty::Dynamic(data, ..) => data.principal_def_id(),
|
|
|
|
|
2023-02-02 13:57:36 +00:00
|
|
|
ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
|
2020-09-15 23:22:24 +00:00
|
|
|
characteristic_def_id_of_type_cached(subty, visited)
|
|
|
|
}
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2024-03-21 21:33:10 +00:00
|
|
|
ty::RawPtr(ty, _) => characteristic_def_id_of_type_cached(ty, visited),
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2020-09-15 23:22:24 +00:00
|
|
|
ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited),
|
2018-12-19 11:25:31 +00:00
|
|
|
|
2023-11-21 19:07:32 +00:00
|
|
|
ty::Tuple(tys) => tys.iter().find_map(|ty| {
|
2020-09-15 23:22:24 +00:00
|
|
|
if visited.insert(ty) {
|
|
|
|
return characteristic_def_id_of_type_cached(ty, visited);
|
|
|
|
}
|
|
|
|
return None;
|
|
|
|
}),
|
2019-12-22 22:42:04 +00:00
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
ty::FnDef(def_id, _)
|
|
|
|
| ty::Closure(def_id, _)
|
2024-01-24 18:01:56 +00:00
|
|
|
| ty::CoroutineClosure(def_id, _)
|
2023-12-21 01:52:10 +00:00
|
|
|
| ty::Coroutine(def_id, _)
|
2023-10-19 16:06:43 +00:00
|
|
|
| ty::CoroutineWitness(def_id, _)
|
2018-12-19 11:25:31 +00:00
|
|
|
| ty::Foreign(def_id) => Some(def_id),
|
2019-12-22 22:42:04 +00:00
|
|
|
|
2018-12-19 11:25:31 +00:00
|
|
|
ty::Bool
|
|
|
|
| ty::Char
|
|
|
|
| ty::Int(_)
|
|
|
|
| ty::Uint(_)
|
|
|
|
| ty::Str
|
2024-08-08 07:18:20 +00:00
|
|
|
| ty::FnPtr(..)
|
2024-12-21 17:05:40 +00:00
|
|
|
| ty::UnsafeBinder(_)
|
2022-11-27 17:52:17 +00:00
|
|
|
| ty::Alias(..)
|
2018-12-19 11:25:31 +00:00
|
|
|
| ty::Placeholder(..)
|
|
|
|
| ty::Param(_)
|
|
|
|
| ty::Infer(_)
|
|
|
|
| ty::Bound(..)
|
2020-05-06 04:02:09 +00:00
|
|
|
| ty::Error(_)
|
2018-12-19 11:25:31 +00:00
|
|
|
| ty::Never
|
|
|
|
| ty::Float(_) => None,
|
|
|
|
}
|
|
|
|
}
|
2020-09-15 23:22:24 +00:00
|
|
|
pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
2020-09-24 04:32:11 +00:00
|
|
|
characteristic_def_id_of_type_cached(ty, &mut SsoHashSet::new())
|
2020-09-15 23:22:24 +00:00
|
|
|
}
|
2019-01-20 02:56:48 +00:00
|
|
|
|
2022-06-19 04:20:27 +00:00
|
|
|
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'tcx> {
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
|
2022-01-28 00:25:15 +00:00
|
|
|
cx.print_region(*self)
|
2019-01-20 02:56:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-13 21:48:52 +00:00
|
|
|
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 03:13:38 +00:00
|
|
|
cx.print_type(*self)
|
2019-01-20 02:56:48 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-24 18:47:02 +00:00
|
|
|
|
2022-11-19 03:28:56 +00:00
|
|
|
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
|
2019-01-24 18:47:02 +00:00
|
|
|
cx.print_dyn_existential(self)
|
|
|
|
}
|
|
|
|
}
|
2019-03-18 10:50:57 +00:00
|
|
|
|
2022-02-02 03:24:45 +00:00
|
|
|
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Const<'tcx> {
|
2023-10-17 17:46:14 +00:00
|
|
|
fn print(&self, cx: &mut P) -> Result<(), PrintError> {
|
2022-02-02 03:24:45 +00:00
|
|
|
cx.print_const(*self)
|
2019-03-18 10:50:57 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-10 18:03:19 +00:00
|
|
|
|
|
|
|
// This is only used by query descriptions
|
2023-04-26 18:53:51 +00:00
|
|
|
pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String {
|
|
|
|
let def_id = def_id.into();
|
2022-10-10 18:03:19 +00:00
|
|
|
if def_id.is_top_level_module() {
|
|
|
|
"top-level module".to_string()
|
|
|
|
} else {
|
2023-02-16 09:25:11 +00:00
|
|
|
format!("module `{}`", tcx.def_path_str(def_id))
|
2022-10-10 18:03:19 +00:00
|
|
|
}
|
|
|
|
}
|
2024-05-10 18:59:56 +00:00
|
|
|
|
|
|
|
impl<T> rustc_type_ir::ir_print::IrPrint<T> for TyCtxt<'_>
|
|
|
|
where
|
|
|
|
T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>>,
|
|
|
|
{
|
|
|
|
fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
ty::tls::with(|tcx| {
|
|
|
|
let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS);
|
|
|
|
tcx.lift(*t).expect("could not lift for printing").print(&mut cx)?;
|
|
|
|
fmt.write_str(&cx.into_buffer())?;
|
|
|
|
Ok(())
|
|
|
|
})
|
|
|
|
}
|
2024-05-10 19:11:09 +00:00
|
|
|
|
|
|
|
fn print_debug(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
with_no_trimmed_paths!(Self::print(t, fmt))
|
|
|
|
}
|
2024-05-10 18:59:56 +00:00
|
|
|
}
|
2024-05-24 18:09:40 +00:00
|
|
|
|
|
|
|
/// Format instance name that is already known to be too long for rustc.
|
|
|
|
/// Show only the first 2 types if it is longer than 32 characters to avoid blasting
|
|
|
|
/// the user's terminal with thousands of lines of type-name.
|
|
|
|
///
|
|
|
|
/// If the type name is longer than before+after, it will be written to a file.
|
|
|
|
pub fn shrunk_instance_name<'tcx>(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
instance: ty::Instance<'tcx>,
|
|
|
|
) -> (String, Option<PathBuf>) {
|
|
|
|
let s = instance.to_string();
|
|
|
|
|
|
|
|
// Only use the shrunk version if it's really shorter.
|
|
|
|
// This also avoids the case where before and after slices overlap.
|
|
|
|
if s.chars().nth(33).is_some() {
|
|
|
|
let shrunk = format!("{}", ShortInstance(instance, 4));
|
|
|
|
if shrunk == s {
|
|
|
|
return (s, None);
|
|
|
|
}
|
|
|
|
|
|
|
|
let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None);
|
|
|
|
let written_to_path = std::fs::write(&path, s).ok().map(|_| path);
|
|
|
|
|
|
|
|
(shrunk, written_to_path)
|
|
|
|
} else {
|
|
|
|
(s, None)
|
|
|
|
}
|
|
|
|
}
|