Rollup merge of #107585 - compiler-errors:fndef-sig-cycle, r=oli-obk
Don't cause a cycle when formatting query description that references a FnDef When a function returns `-> _`, we use typeck to compute what the resulting type of the body _should_ be. If we call another query inside of typeck and hit a cycle error, we attempt to report the cycle error which requires us to compute all of the query descriptions for the stack. However, if one of the queries in that cycle has a query description that references this function as a FnDef type, we'll cause a *second* cycle error from within the cycle error reporting code, since rendering a FnDef requires us to compute its signature. This causes an unwrap to ICE, since during the *second* cycle reporting code, we try to look for a job that isn't in the active jobs list. We can avoid this by using `with_no_queries!` when computing these query descriptions. Fixes #107089 The only drawback is that the rendering of opaque types in cycles regresses a bit :| I'm open to alternate suggestions about how we may handle this...
This commit is contained in:
commit
d6f0c51e98
7 changed files with 51 additions and 20 deletions
|
@ -675,8 +675,12 @@ pub trait PrettyPrinter<'tcx>:
|
|||
p!(")")
|
||||
}
|
||||
ty::FnDef(def_id, substs) => {
|
||||
let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
|
||||
p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
|
||||
if NO_QUERIES.with(|q| q.get()) {
|
||||
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::Infer(infer_ty) => {
|
||||
|
@ -734,13 +738,13 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
|
||||
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
|
||||
// avoid needing to call `predicates_of`. This should
|
||||
// only affect certain debug messages (e.g. messages printed
|
||||
// from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
|
||||
// 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));
|
||||
return Ok(self);
|
||||
}
|
||||
|
@ -748,6 +752,8 @@ pub trait PrettyPrinter<'tcx>:
|
|||
let parent = self.tcx().parent(def_id);
|
||||
match self.tcx().def_kind(parent) {
|
||||
DefKind::TyAlias | DefKind::AssocTy => {
|
||||
// NOTE: I know we should check for NO_QUERIES here, but it's alright.
|
||||
// `type_of` on a type alias or assoc type should never cause a cycle.
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
|
||||
*self.tcx().type_of(parent).kind()
|
||||
{
|
||||
|
@ -762,7 +768,14 @@ pub trait PrettyPrinter<'tcx>:
|
|||
p!(print_def_path(def_id, substs));
|
||||
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"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue