assert_inhabited | assert_zero_valid | assert_uninit_valid, <T> () {
let layout = fx.layout_of(T);
if layout.abi.is_uninhabited() {
- with_no_trimmed_paths(|| crate::base::codegen_panic(
- fx,
- &format!("attempted to instantiate uninhabited type `{}`", T),
- span,
- ));
+ with_no_trimmed_paths!({
+ crate::base::codegen_panic(
+ fx,
+ &format!("attempted to instantiate uninhabited type `{}`", T),
+ span,
+ )
+ });
return;
}
if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) {
- with_no_trimmed_paths(|| crate::base::codegen_panic(
- fx,
- &format!("attempted to zero-initialize type `{}`, which is invalid", T),
- span,
- ));
+ with_no_trimmed_paths!({
+ crate::base::codegen_panic(
+ fx,
+ &format!("attempted to zero-initialize type `{}`, which is invalid", T),
+ span,
+ );
+ });
return;
}
if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) {
- with_no_trimmed_paths(|| crate::base::codegen_panic(
- fx,
- &format!("attempted to leave type `{}` uninitialized, which is invalid", T),
- span,
- ));
+ with_no_trimmed_paths!({
+ crate::base::codegen_panic(
+ fx,
+ &format!("attempted to leave type `{}` uninitialized, which is invalid", T),
+ span,
+ )
+ });
return;
}
};
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
if !cx.sess().fewer_names() =>
{
- let mut name = with_no_trimmed_paths(|| layout.ty.to_string());
+ let mut name = with_no_trimmed_paths!(layout.ty.to_string());
if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
{
// in problematically distinct types due to HRTB and subtyping (see #47638).
// ty::Dynamic(..) |
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str => {
- let mut name =
- with_no_visible_paths(|| with_no_trimmed_paths(|| layout.ty.to_string()));
+ let mut name = with_no_visible_paths!(with_no_trimmed_paths!(layout.ty.to_string()));
if let (&ty::Adt(def, _), &Variants::Single { index }) =
(layout.ty.kind(), &layout.variants)
{
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false),
};
if do_panic {
- let msg_str = with_no_visible_paths(|| {
- with_no_trimmed_paths(|| {
+ let msg_str = with_no_visible_paths!({
+ with_no_trimmed_paths!({
if layout.abi.is_uninhabited() {
// Use this error even for the other intrinsics as it is more precise.
format!("attempted to instantiate uninhabited type `{}`", ty)
trace!(
"eval_body_using_ecx: pushing stack frame for global: {}{}",
- with_no_trimmed_paths(|| ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()))),
+ with_no_trimmed_paths!(ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()))),
cid.promoted.map_or_else(String::new, |p| format!("::promoted[{:?}]", p))
);
// The next two lines concatenated contain some discussion:
// https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
// subject/anon_const_instance_printing/near/135980032
- let instance = with_no_trimmed_paths(|| key.value.instance.to_string());
+ let instance = with_no_trimmed_paths!(key.value.instance.to_string());
trace!("const eval: {:?} ({})", key, instance);
}
// the expression, leading to the const eval error.
let instance = &key.value.instance;
if !instance.substs.is_empty() {
- let instance = with_no_trimmed_paths(|| instance.to_string());
+ let instance = with_no_trimmed_paths!(instance.to_string());
let msg = format!("evaluation of `{}` failed", instance);
Cow::from(msg)
} else {
msg.push_str(", but expected ");
write!(&mut msg, $($expected_fmt),+).unwrap();
)?
- let path = rustc_middle::ty::print::with_no_trimmed_paths(|| {
+ let path = rustc_middle::ty::print::with_no_trimmed_paths!({
let where_ = &$where;
if !where_.is_empty() {
let mut path = String::new();
.as_ref()
.and_then(|node| node.generics())
{
- let constraint = with_no_trimmed_paths(|| {
- format!("~const {}", trait_ref.print_only_trait_path())
- });
+ let constraint = with_no_trimmed_paths!(format!(
+ "~const {}",
+ trait_ref.print_only_trait_path()
+ ));
suggest_constraining_type_param(
tcx,
generics,
// We are extremely conservative with what we warn about.
let conjured_ty = cx.typeck_results().expr_ty(expr);
if let Some((msg, span)) =
- with_no_trimmed_paths(|| ty_find_init_error(cx.tcx, conjured_ty, init))
+ with_no_trimmed_paths!(ty_find_init_error(cx.tcx, conjured_ty, init))
{
cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| {
let mut err = lint.build(&format!(
}
// This shouldn't ever be needed, but just in case:
- with_no_trimmed_paths(|| {
+ with_no_trimmed_paths!({
Ok(vec![match trait_ref {
Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)),
None => Symbol::intern(&format!("<{}>", self_ty)),
// This shouldn't ever be needed, but just in case:
path.push(match trait_ref {
- Some(trait_ref) => with_no_trimmed_paths(|| {
- Symbol::intern(&format!(
+ Some(trait_ref) => {
+ with_no_trimmed_paths!(Symbol::intern(&format!(
"<impl {} for {}>",
trait_ref.print_only_trait_path(),
self_ty
- ))
- }),
+ )))
+ }
None => {
- with_no_trimmed_paths(|| Symbol::intern(&format!("<impl {}>", self_ty)))
+ with_no_trimmed_paths!(Symbol::intern(&format!("<impl {}>", self_ty)))
}
});
#[allow(unused_variables)]
fn describe(tcx: QueryCtxt<$tcx>, key: Self::Key) -> String {
let (#tcx, #key) = (*tcx, key);
- ::rustc_middle::ty::print::with_no_trimmed_paths(|| format!(#desc).into())
+ ::rustc_middle::ty::print::with_no_trimmed_paths!(
+ format!(#desc)
+ )
}
};
#![feature(try_reserve_kind)]
#![feature(nonzero_ops)]
#![feature(unwrap_infallible)]
+#![feature(decl_macro)]
#![recursion_limit = "512"]
#![cfg_attr(not(bootstrap), allow(rustc::potential_query_instability))]
let is_in_effect = deprecation_in_effect(depr_attr);
let lint = deprecation_lint(is_in_effect);
if self.lint_level_at_node(lint, id).0 != Level::Allow {
- let def_path = &with_no_trimmed_paths(|| self.def_path_str(def_id));
+ let def_path = with_no_trimmed_paths!(self.def_path_str(def_id));
let def_kind = self.def_kind(def_id).descr(def_id);
late_report_deprecation(
depr_attr.since,
depr_attr.note,
def_kind,
- def_path,
+ &def_path,
),
depr_attr.suggestion,
lint,
impl<'tcx> GlobalId<'tcx> {
pub fn display(self, tcx: TyCtxt<'tcx>) -> String {
- let instance_name = with_no_trimmed_paths(|| tcx.def_path_str(self.instance.def.def_id()));
+ let instance_name = with_no_trimmed_paths!(tcx.def_path_str(self.instance.def.def_id()));
if let Some(promoted) = self.promoted {
format!("{}::{:?}", instance_name, promoted)
} else {
None => return false,
Some(ref filters) => filters,
};
- let node_path = ty::print::with_forced_impl_filename_line(|| {
- // see notes on #41697 below
- tcx.def_path_str(def_id)
- });
+ // see notes on #41697 below
+ let node_path = ty::print::with_forced_impl_filename_line!(tcx.def_path_str(def_id));
filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| {
let and_filter_trimmed = and_filter.trim();
let _: io::Result<()> = try {
let mut file =
create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, body.source)?;
- let def_path = ty::print::with_forced_impl_filename_line(|| {
- // see notes on #41697 above
- tcx.def_path_str(body.source.def_id())
- });
+ // see notes on #41697 above
+ let def_path =
+ ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id()));
write!(file, "// MIR for `{}", def_path)?;
match body.source.promoted {
None => write!(file, "`")?,
_ => bug!("Unexpected def kind {:?}", kind),
}
- ty::print::with_forced_impl_filename_line(|| {
+ ty::print::with_forced_impl_filename_line! {
// see notes on #41697 elsewhere
- write!(w, "{}", tcx.def_path_str(def_id))
- })?;
+ write!(w, "{}", tcx.def_path_str(def_id))?
+ }
if body.source.promoted.is_none() && is_function {
write!(w, "(")?;
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
}
-/// Avoids running any queries during any prints that occur
-/// during the closure. This may alter the appearance of some
-/// types (e.g. forcing verbose printing for opaque types).
-/// This method is used during some queries (e.g. `explicit_item_bounds`
-/// for opaque types), to ensure that any debug printing that
-/// occurs during the query computation does not end up recursively
-/// calling the same query.
-pub fn with_no_queries<F: FnOnce() -> R, R>(f: F) -> R {
- NO_QUERIES.with(|no_queries| {
- let old = no_queries.replace(true);
- let result = f();
- no_queries.set(old);
- result
- })
-}
-
-/// Force us to name impls with just the filename/line number. We
-/// normally try to use types. But at some points, notably while printing
-/// cycle errors, this can result in extra or suboptimal error output,
-/// so this variable disables that check.
-pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
- FORCE_IMPL_FILENAME_LINE.with(|force| {
- let old = force.replace(true);
- let result = f();
- force.set(old);
- result
- })
-}
+macro_rules! define_helper {
+ ($($(#[$a:meta])* fn $name:ident($helper:ident, $tl:ident);)+) => {
+ $(
+ #[must_use]
+ pub struct $helper(bool);
+
+ impl $helper {
+ pub fn new() -> $helper {
+ $helper($tl.with(|c| c.replace(true)))
+ }
+ }
-/// Adds the `crate::` prefix to paths where appropriate.
-pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
- SHOULD_PREFIX_WITH_CRATE.with(|flag| {
- let old = flag.replace(true);
- let result = f();
- flag.set(old);
- result
- })
-}
+ $(#[$a])*
+ pub macro $name($e:expr) {
+ {
+ let _guard = $helper::new();
+ $e
+ }
+ }
-/// Prevent path trimming if it is turned on. Path trimming affects `Display` impl
-/// of various rustc types, for example `std::vec::Vec` would be trimmed to `Vec`,
-/// if no other `Vec` is found.
-pub fn with_no_trimmed_paths<F: FnOnce() -> R, R>(f: F) -> R {
- NO_TRIMMED_PATH.with(|flag| {
- let old = flag.replace(true);
- let result = f();
- flag.set(old);
- result
- })
+ impl Drop for $helper {
+ fn drop(&mut self) {
+ $tl.with(|c| c.set(self.0))
+ }
+ }
+ )+
+ }
}
-/// Prevent selection of visible paths. `Display` impl of DefId will prefer visible (public) reexports of types as paths.
-pub fn with_no_visible_paths<F: FnOnce() -> R, R>(f: F) -> R {
- NO_VISIBLE_PATH.with(|flag| {
- let old = flag.replace(true);
- let result = f();
- flag.set(old);
- result
- })
-}
+define_helper!(
+ /// Avoids running any queries during any prints that occur
+ /// during the closure. This may alter the appearance of some
+ /// types (e.g. forcing verbose printing for opaque types).
+ /// This method is used during some queries (e.g. `explicit_item_bounds`
+ /// for opaque types), to ensure that any debug printing that
+ /// occurs during the query computation does not end up recursively
+ /// calling the same query.
+ fn with_no_queries(NoQueriesGuard, NO_QUERIES);
+ /// Force us to name impls with just the filename/line number. We
+ /// normally try to use types. But at some points, notably while printing
+ /// cycle errors, this can result in extra or suboptimal error output,
+ /// so this variable disables that check.
+ fn with_forced_impl_filename_line(ForcedImplGuard, FORCE_IMPL_FILENAME_LINE);
+ /// Adds the `crate::` prefix to paths where appropriate.
+ fn with_crate_prefix(CratePrefixGuard, SHOULD_PREFIX_WITH_CRATE);
+ /// Prevent path trimming if it is turned on. Path trimming affects `Display` impl
+ /// of various rustc types, for example `std::vec::Vec` would be trimmed to `Vec`,
+ /// if no other `Vec` is found.
+ fn with_no_trimmed_paths(NoTrimmedGuard, NO_TRIMMED_PATH);
+ /// Prevent selection of visible paths. `Display` impl of DefId will prefer
+ /// visible (public) reexports of types as paths.
+ fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
+);
/// The "region highlights" are used to control region printing during
/// specific error messages. When a "region highlight" is enabled, it
// in cases where the `extern crate foo` has non-trivial
// parents, e.g. it's nested in `impl foo::Trait for Bar`
// (see also issues #55779 and #87932).
- self = with_no_visible_paths(|| self.print_def_path(def_id, &[]))?;
+ self = with_no_visible_paths!(self.print_def_path(def_id, &[])?);
return Ok((self, true));
}
return Ok(self);
}
- return with_no_queries(|| {
+ return with_no_queries!({
let def_key = self.tcx().def_key(def_id);
if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
p!(write("{}", name));
impl fmt::Debug for ty::TraitDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
- with_no_trimmed_paths(|| {
- FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.def_id, &[])
- })?;
+ with_no_trimmed_paths!(
+ FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.def_id, &[])?
+ );
Ok(())
})
}
impl fmt::Debug for ty::AdtDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
ty::tls::with(|tcx| {
- with_no_trimmed_paths(|| {
- FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.did, &[])
- })?;
+ with_no_trimmed_paths!(
+ FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.did, &[])?
+ );
Ok(())
})
}
impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- with_no_trimmed_paths(|| fmt::Display::fmt(self, f))
+ with_no_trimmed_paths!(fmt::Display::fmt(self, f))
}
}
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- with_no_trimmed_paths(|| fmt::Display::fmt(self, f))
+ with_no_trimmed_paths!(fmt::Display::fmt(self, f))
}
}
impl<'tcx> fmt::Debug for Ty<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- with_no_trimmed_paths(|| fmt::Display::fmt(self, f))
+ with_no_trimmed_paths!(fmt::Display::fmt(self, f))
}
}
fn search_for_structural_match_violation(&self, ty: Ty<'tcx>) -> Option<String> {
traits::search_for_structural_match_violation(self.span, self.tcx(), ty).map(|non_sm_ty| {
- with_no_trimmed_paths(|| match non_sm_ty {
+ with_no_trimmed_paths!(match non_sm_ty {
traits::NonStructuralMatchTy::Adt(adt) => self.adt_derive_msg(adt),
traits::NonStructuralMatchTy::Dynamic => {
"trait objects cannot be used in patterns".to_string()
&& starting_point.node.krate() != LOCAL_CRATE
&& starting_point.node.is_user_defined()
{
- let formatted_item = with_no_trimmed_paths(|| starting_point.node.to_string());
+ let formatted_item = with_no_trimmed_paths!(starting_point.node.to_string());
tcx.sess.span_note_without_error(
starting_point.span,
&format!("the above error was encountered while instantiating `{}`", formatted_item),
let mut item_keys: Vec<_> = items
.iter()
.map(|i| {
- let mut output = with_no_trimmed_paths(|| i.to_string());
+ let mut output = with_no_trimmed_paths!(i.to_string());
output.push_str(" @@");
let mut empty = Vec::new();
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
let name = stringify!($name);
// Disable visible paths printing for performance reasons.
// Showing visible path instead of any path is not that important in production.
- let description = ty::print::with_no_visible_paths(
- || ty::print::with_forced_impl_filename_line(
+ let description = ty::print::with_no_visible_paths!(
// Force filename-line mode to avoid invoking `type_of` query.
- || queries::$name::describe(tcx, key)
- ));
+ ty::print::with_forced_impl_filename_line!(
+ queries::$name::describe(tcx, key)
+ )
+ );
let description = if tcx.sess.verbose() {
format!("{} [{}]", description, name)
} else {
config: Option<Config>,
mut handler: H,
) {
- with_no_trimmed_paths(|| {
+ with_no_trimmed_paths!({
tcx.dep_graph.with_ignore(|| {
info!("Dumping crate {}", cratename);
tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
}
} else if attr.has_name(DEF_PATH) {
- let path = with_no_trimmed_paths(|| tcx.def_path_str(def_id.to_def_id()));
+ let path = with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id()));
tcx.sess.span_err(attr.span, &format!("def-path({})", path));
}
}
// Add all types without trimmed paths.
- ty::print::with_no_trimmed_paths(|| {
+ ty::print::with_no_trimmed_paths!({
let generics = self.tcx.generics_of(def_id);
let self_ty = trait_ref.self_ty();
// This is also included through the generics list as `Self`,
{
// Missing generic type parameter bound.
let param_name = self_ty.to_string();
- let constraint = with_no_trimmed_paths(|| {
+ let constraint = with_no_trimmed_paths!(
trait_pred.print_modifiers_and_trait_path().to_string()
- });
+ );
if suggest_constraining_type_param(
self.tcx,
generics,
if !candidate_set.ambiguous && no_candidates_apply {
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
let self_ty = trait_ref.self_ty();
- let (trait_desc, self_desc) = with_no_trimmed_paths(|| {
+ let (trait_desc, self_desc) = with_no_trimmed_paths!({
let trait_desc = trait_ref.print_only_trait_path().to_string();
let self_desc = if self_ty.has_concrete_skeleton() {
Some(self_ty.to_string())
if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
let self_ty = trait_ref.self_ty();
- let cause = with_no_trimmed_paths(|| {
+ let cause = with_no_trimmed_paths!({
IntercrateAmbiguityCause::DownstreamCrate {
trait_desc: trait_ref.print_only_trait_path().to_string(),
self_desc: if self_ty.has_concrete_skeleton() {
let self_ty = trait_ref.self_ty();
// FIXME: should postpone string formatting until we decide to actually emit.
- with_no_trimmed_paths(|| {
+ with_no_trimmed_paths!({
OverlapError {
with_impl: possible_sibling,
trait_desc: trait_ref.print_only_trait_path().to_string(),
let sole_field_ty = sole_field.ty(self.tcx, substs);
if self.can_coerce(expr_ty, sole_field_ty) {
let variant_path =
- with_no_trimmed_paths(|| self.tcx.def_path_str(variant.def_id));
+ with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
// FIXME #56861: DRYer prelude filtering
if let Some(path) = variant_path.strip_prefix("std::prelude::") {
if let Some((_, path)) = path.split_once("::") {
let additional_newline = if found_use { "" } else { "\n" };
format!(
"use {};\n{}",
- with_crate_prefix(|| self.tcx.def_path_str(*trait_did)),
+ with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
additional_newline
)
});
let additional_newline = if found_use { "" } else { "\n" };
format!(
"use {}::*; // trait {}\n{}",
- with_crate_prefix(|| self.tcx.def_path_str(*parent_did)),
+ with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
additional_newline
)
msg.push_str(&format!(
"\ncandidate #{}: `use {};`",
i + 1,
- with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
+ with_crate_prefix!(self.tcx.def_path_str(*trait_did))
));
} else {
msg.push_str(&format!(
"\n`use {};`",
- with_crate_prefix(|| self.tcx.def_path_str(*trait_did))
+ with_crate_prefix!(self.tcx.def_path_str(*trait_did))
));
}
}
msg.push_str(&format!(
"\ncandidate #{}: `use {}::*; // trait {}`",
candidates.len() + i + 1,
- with_crate_prefix(|| self.tcx.def_path_str(*parent_did)),
+ with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
));
} else {
msg.push_str(&format!(
"\n`use {}::*; // trait {}`",
- with_crate_prefix(|| self.tcx.def_path_str(*parent_did)),
+ with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
));
}
if let Some(did) = edition_fix {
err.note(&format!(
"'{}' is included in the prelude starting in Edition 2021",
- with_crate_prefix(|| self.tcx.def_path_str(did))
+ with_crate_prefix!(self.tcx.def_path_str(did))
));
}
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
span: Span,
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
- ty::print::with_no_queries(|| {
+ ty::print::with_no_queries!({
let item_ty =
tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));