Don't cause a cycle when formatting query description that references a FnDef

This commit is contained in:
Michael Goulet 2023-02-02 05:49:07 +00:00
parent e63ec2e140
commit 64f5293956
7 changed files with 51 additions and 20 deletions

View file

@ -675,8 +675,12 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
p!(")") p!(")")
} }
ty::FnDef(def_id, substs) => { ty::FnDef(def_id, substs) => {
let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); if NO_QUERIES.with(|q| q.get()) {
p!(print(sig), " {{", print_value_path(def_id, substs), "}}"); p!(print_def_path(def_id, substs));
} else {
let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
}
} }
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
ty::Infer(infer_ty) => { ty::Infer(infer_ty) => {
@ -732,13 +736,13 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
} }
ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
// FIXME(eddyb) print this with `print_def_path`.
// We use verbose printing in 'NO_QUERIES' mode, to // We use verbose printing in 'NO_QUERIES' mode, to
// avoid needing to call `predicates_of`. This should // avoid needing to call `predicates_of`. This should
// only affect certain debug messages (e.g. messages printed // only affect certain debug messages (e.g. messages printed
// from `rustc_middle::ty` during the computation of `tcx.predicates_of`), // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
// and should have no effect on any compiler output. // and should have no effect on any compiler output.
if self.should_print_verbose() || NO_QUERIES.with(|q| q.get()) { if self.should_print_verbose() {
// FIXME(eddyb) print this with `print_def_path`.
p!(write("Opaque({:?}, {:?})", def_id, substs)); p!(write("Opaque({:?}, {:?})", def_id, substs));
return Ok(self); return Ok(self);
} }
@ -746,6 +750,8 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
let parent = self.tcx().parent(def_id); let parent = self.tcx().parent(def_id);
match self.tcx().def_kind(parent) { match self.tcx().def_kind(parent) {
DefKind::TyAlias | DefKind::AssocTy => { DefKind::TyAlias | DefKind::AssocTy => {
// NOTE: I know we should check for NO_QUERIES here, but it's alright.
// `type_of` on a TAIT should never cause a cycle.
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) = if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
*self.tcx().type_of(parent).kind() *self.tcx().type_of(parent).kind()
{ {
@ -760,7 +766,14 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
p!(print_def_path(def_id, substs)); p!(print_def_path(def_id, substs));
return Ok(self); return Ok(self);
} }
_ => return self.pretty_print_opaque_impl_type(def_id, substs), _ => {
if NO_QUERIES.with(|q| q.get()) {
p!(print_def_path(def_id, &[]));
return Ok(self);
} else {
return self.pretty_print_opaque_impl_type(def_id, substs);
}
}
} }
} }
ty::Str => p!("str"), ty::Str => p!("str"),

View file

@ -314,11 +314,14 @@ pub(crate) fn create_query_frame<
kind: DepKind, kind: DepKind,
name: &'static str, name: &'static str,
) -> QueryStackFrame<DepKind> { ) -> QueryStackFrame<DepKind> {
// Disable visible paths printing for performance reasons. // Avoid calling queries while formatting the description
// Showing visible path instead of any path is not that important in production. let description = ty::print::with_no_queries!(
let description = ty::print::with_no_visible_paths!( // Disable visible paths printing for performance reasons.
// Force filename-line mode to avoid invoking `type_of` query. // Showing visible path instead of any path is not that important in production.
ty::print::with_forced_impl_filename_line!(do_describe(tcx.tcx, key)) ty::print::with_no_visible_paths!(
// Force filename-line mode to avoid invoking `type_of` query.
ty::print::with_forced_impl_filename_line!(do_describe(tcx.tcx, key))
)
); );
let description = let description =
if tcx.sess.verbose() { format!("{description} [{name:?}]") } else { description }; if tcx.sess.verbose() { format!("{description} [{name:?}]") } else { description };

View file

@ -28,8 +28,8 @@ note: ...which requires const checking `x`...
| |
LL | pub const async fn x() {} LL | pub const async fn x() {}
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `x::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `x::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `x::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `x::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/no-const-async.rs:4:1 --> $DIR/no-const-async.rs:4:1

View file

@ -39,7 +39,7 @@ note: ...which requires type-checking `cycle1`...
| |
LL | send(cycle2().clone()); LL | send(cycle2().clone());
| ^^^^ | ^^^^
= note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... = note: ...which requires evaluating trait selection obligation `cycle2::{opaque#0}: core::marker::Send`...
note: ...which requires computing type of `cycle2::{opaque#0}`... note: ...which requires computing type of `cycle2::{opaque#0}`...
--> $DIR/auto-trait-leak.rs:19:16 --> $DIR/auto-trait-leak.rs:19:16
| |
@ -80,7 +80,7 @@ note: ...which requires type-checking `cycle2`...
| |
LL | send(cycle1().clone()); LL | send(cycle1().clone());
| ^^^^ | ^^^^
= note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... = note: ...which requires evaluating trait selection obligation `cycle1::{opaque#0}: core::marker::Send`...
= note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/auto-trait-leak.rs:1:1 --> $DIR/auto-trait-leak.rs:1:1

View file

@ -209,8 +209,8 @@ note: ...which requires const checking `main::ff5`...
| |
LL | const async unsafe extern "C" fn ff5() {} LL | const async unsafe extern "C" fn ff5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `main::ff5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `main::ff5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `main::ff5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1 --> $DIR/fn-header-semantic-fail.rs:5:1
@ -245,8 +245,8 @@ note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-f
| |
LL | const async unsafe extern "C" fn ft5() {} LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1 --> $DIR/fn-header-semantic-fail.rs:5:1
@ -281,8 +281,8 @@ note: ...which requires const checking `main::<impl at $DIR/fn-header-semantic-f
| |
LL | const async unsafe extern "C" fn fi5() {} LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing whether `impl core::future::future::Future<Output = ()>` is freeze... = note: ...which requires computing whether `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}` is freeze...
= note: ...which requires evaluating trait selection obligation `impl core::future::future::Future<Output = ()>: core::marker::Freeze`... = note: ...which requires evaluating trait selection obligation `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}: core::marker::Freeze`...
= note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`, completing the cycle = note: ...which again requires computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:40:5: 40:11>::fi5::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module note: cycle used when checking item types in top-level module
--> $DIR/fn-header-semantic-fail.rs:5:1 --> $DIR/fn-header-semantic-fail.rs:5:1

View file

@ -0,0 +1,6 @@
fn a() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
&a
}
fn main() {}

View file

@ -0,0 +1,9 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/no-query-in-printing-during-query-descr.rs:1:11
|
LL | fn a() -> _ {
| ^ not allowed in type signatures
error: aborting due to previous error
For more information about this error, try `rustc --explain E0121`.