mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Run code formatter
This commit is contained in:
@@ -9,10 +9,10 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_middle::dep_graph::DepKind;
|
||||
use rustc_middle::queries::QueryVTables;
|
||||
use rustc_middle::query::CycleError;
|
||||
use rustc_middle::query::erase::erase_val;
|
||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::queries::QueryVTables;
|
||||
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
@@ -49,102 +49,106 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) {
|
||||
|tcx, cycle, guar| erase_val(layout_of(tcx, cycle, guar));
|
||||
}
|
||||
|
||||
pub(crate) fn default<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, query_name: &str) -> ! {
|
||||
let Some(guar) = tcx.sess.dcx().has_errors() else {
|
||||
bug!(
|
||||
"`from_cycle_error_default` on query `{query_name}` called without errors: {:#?}",
|
||||
cycle_error.cycle,
|
||||
);
|
||||
};
|
||||
guar.raise_fatal()
|
||||
}
|
||||
pub(crate) fn default<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, query_name: &str) -> ! {
|
||||
let Some(guar) = tcx.sess.dcx().has_errors() else {
|
||||
bug!(
|
||||
"`from_cycle_error_default` on query `{query_name}` called without errors: {:#?}",
|
||||
cycle_error.cycle,
|
||||
);
|
||||
};
|
||||
guar.raise_fatal()
|
||||
}
|
||||
|
||||
fn fn_sig<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, guar: ErrorGuaranteed) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
|
||||
let err = Ty::new_error(tcx, guar);
|
||||
fn fn_sig<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
guar: ErrorGuaranteed,
|
||||
) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
|
||||
let err = Ty::new_error(tcx, guar);
|
||||
|
||||
let arity = if let Some(info) = cycle_error.cycle.get(0)
|
||||
&& info.frame.dep_kind == DepKind::fn_sig
|
||||
&& let Some(def_id) = info.frame.def_id
|
||||
&& let Some(node) = tcx.hir_get_if_local(def_id)
|
||||
&& let Some(sig) = node.fn_sig()
|
||||
let arity = if let Some(info) = cycle_error.cycle.get(0)
|
||||
&& info.frame.dep_kind == DepKind::fn_sig
|
||||
&& let Some(def_id) = info.frame.def_id
|
||||
&& let Some(node) = tcx.hir_get_if_local(def_id)
|
||||
&& let Some(sig) = node.fn_sig()
|
||||
{
|
||||
sig.decl.inputs.len()
|
||||
} else {
|
||||
tcx.dcx().abort_if_errors();
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
ty::EarlyBinder::bind(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
std::iter::repeat_n(err, arity),
|
||||
err,
|
||||
false,
|
||||
rustc_hir::Safety::Safe,
|
||||
rustc_abi::ExternAbi::Rust,
|
||||
)))
|
||||
}
|
||||
|
||||
fn check_representability<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> ! {
|
||||
let mut item_and_field_ids = Vec::new();
|
||||
let mut representable_ids = FxHashSet::default();
|
||||
for info in &cycle_error.cycle {
|
||||
if info.frame.dep_kind == DepKind::check_representability
|
||||
&& let Some(field_id) = info.frame.def_id
|
||||
&& let Some(field_id) = field_id.as_local()
|
||||
&& let Some(DefKind::Field) = info.frame.info.def_kind
|
||||
{
|
||||
sig.decl.inputs.len()
|
||||
} else {
|
||||
tcx.dcx().abort_if_errors();
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
ty::EarlyBinder::bind(ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
std::iter::repeat_n(err, arity),
|
||||
err,
|
||||
false,
|
||||
rustc_hir::Safety::Safe,
|
||||
rustc_abi::ExternAbi::Rust,
|
||||
)))
|
||||
}
|
||||
|
||||
fn check_representability<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> ! {
|
||||
let mut item_and_field_ids = Vec::new();
|
||||
let mut representable_ids = FxHashSet::default();
|
||||
for info in &cycle_error.cycle {
|
||||
if info.frame.dep_kind == DepKind::check_representability
|
||||
&& let Some(field_id) = info.frame.def_id
|
||||
&& let Some(field_id) = field_id.as_local()
|
||||
&& let Some(DefKind::Field) = info.frame.info.def_kind
|
||||
{
|
||||
let parent_id = tcx.parent(field_id.to_def_id());
|
||||
let item_id = match tcx.def_kind(parent_id) {
|
||||
DefKind::Variant => tcx.parent(parent_id),
|
||||
_ => parent_id,
|
||||
};
|
||||
item_and_field_ids.push((item_id.expect_local(), field_id));
|
||||
}
|
||||
let parent_id = tcx.parent(field_id.to_def_id());
|
||||
let item_id = match tcx.def_kind(parent_id) {
|
||||
DefKind::Variant => tcx.parent(parent_id),
|
||||
_ => parent_id,
|
||||
};
|
||||
item_and_field_ids.push((item_id.expect_local(), field_id));
|
||||
}
|
||||
for info in &cycle_error.cycle {
|
||||
if info.frame.dep_kind == DepKind::check_representability_adt_ty
|
||||
&& let Some(def_id) = info.frame.def_id_for_ty_in_cycle
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& !item_and_field_ids.iter().any(|&(id, _)| id == def_id)
|
||||
{
|
||||
representable_ids.insert(def_id);
|
||||
}
|
||||
}
|
||||
for info in &cycle_error.cycle {
|
||||
if info.frame.dep_kind == DepKind::check_representability_adt_ty
|
||||
&& let Some(def_id) = info.frame.def_id_for_ty_in_cycle
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& !item_and_field_ids.iter().any(|&(id, _)| id == def_id)
|
||||
{
|
||||
representable_ids.insert(def_id);
|
||||
}
|
||||
// We used to continue here, but the cycle error printed next is actually less useful than
|
||||
// the error produced by `recursive_type_error`.
|
||||
let guar = recursive_type_error(tcx, item_and_field_ids, &representable_ids);
|
||||
guar.raise_fatal()
|
||||
}
|
||||
// We used to continue here, but the cycle error printed next is actually less useful than
|
||||
// the error produced by `recursive_type_error`.
|
||||
let guar = recursive_type_error(tcx, item_and_field_ids, &representable_ids);
|
||||
guar.raise_fatal()
|
||||
}
|
||||
|
||||
fn variances_of<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> &'tcx [ty::Variance] {
|
||||
search_for_cycle_permutation(
|
||||
&cycle_error.cycle,
|
||||
|cycle| {
|
||||
if let Some(info) = cycle.get(0)
|
||||
&& info.frame.dep_kind == DepKind::variances_of
|
||||
&& let Some(def_id) = info.frame.def_id
|
||||
{
|
||||
let n = tcx.generics_of(def_id).own_params.len();
|
||||
ControlFlow::Break(tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n)))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
},
|
||||
|| {
|
||||
span_bug!(
|
||||
cycle_error.usage.as_ref().unwrap().0,
|
||||
"only `variances_of` returns `&[ty::Variance]`"
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
fn variances_of<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> &'tcx [ty::Variance] {
|
||||
search_for_cycle_permutation(
|
||||
&cycle_error.cycle,
|
||||
|cycle| {
|
||||
if let Some(info) = cycle.get(0)
|
||||
&& info.frame.dep_kind == DepKind::variances_of
|
||||
&& let Some(def_id) = info.frame.def_id
|
||||
{
|
||||
let n = tcx.generics_of(def_id).own_params.len();
|
||||
ControlFlow::Break(tcx.arena.alloc_from_iter(iter::repeat_n(ty::Bivariant, n)))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
},
|
||||
|| {
|
||||
span_bug!(
|
||||
cycle_error.usage.as_ref().unwrap().0,
|
||||
"only `variances_of` returns `&[ty::Variance]`"
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Take a cycle of `Q` and try `try_cycle` on every permutation, falling back to `otherwise`.
|
||||
fn search_for_cycle_permutation<Q, T>(
|
||||
@@ -165,90 +169,89 @@ fn search_for_cycle_permutation<Q, T>(
|
||||
otherwise()
|
||||
}
|
||||
|
||||
fn layout_of<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Result<TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
let diag = search_for_cycle_permutation(
|
||||
&cycle_error.cycle,
|
||||
|cycle| {
|
||||
if cycle[0].frame.dep_kind == DepKind::layout_of
|
||||
&& let Some(def_id) = cycle[0].frame.def_id_for_ty_in_cycle
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& let def_kind = tcx.def_kind(def_id)
|
||||
&& matches!(def_kind, DefKind::Closure)
|
||||
&& let Some(coroutine_kind) = tcx.coroutine_kind(def_id)
|
||||
{
|
||||
// FIXME: `def_span` for an fn-like coroutine will point to the fn's body
|
||||
// due to interactions between the desugaring into a closure expr and the
|
||||
// def_span code. I'm not motivated to fix it, because I tried and it was
|
||||
// not working, so just hack around it by grabbing the parent fn's span.
|
||||
let span = if coroutine_kind.is_fn_like() {
|
||||
tcx.def_span(tcx.local_parent(def_id))
|
||||
} else {
|
||||
tcx.def_span(def_id)
|
||||
};
|
||||
let mut diag = struct_span_code_err!(
|
||||
tcx.sess.dcx(),
|
||||
span,
|
||||
E0733,
|
||||
"recursion in {} {} requires boxing",
|
||||
tcx.def_kind_descr_article(def_kind, def_id.to_def_id()),
|
||||
tcx.def_kind_descr(def_kind, def_id.to_def_id()),
|
||||
);
|
||||
for (i, info) in cycle.iter().enumerate() {
|
||||
if info.frame.dep_kind != DepKind::layout_of {
|
||||
continue;
|
||||
}
|
||||
let Some(frame_def_id) = info.frame.def_id_for_ty_in_cycle else {
|
||||
continue;
|
||||
};
|
||||
let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else {
|
||||
continue;
|
||||
};
|
||||
let frame_span =
|
||||
info.frame.info.default_span(cycle[(i + 1) % cycle.len()].span);
|
||||
if frame_span.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
if i == 0 {
|
||||
diag.span_label(frame_span, "recursive call here");
|
||||
} else {
|
||||
let coroutine_span: Span = if frame_coroutine_kind.is_fn_like() {
|
||||
tcx.def_span(tcx.parent(frame_def_id))
|
||||
} else {
|
||||
tcx.def_span(frame_def_id)
|
||||
};
|
||||
let mut multispan = MultiSpan::from_span(coroutine_span);
|
||||
multispan
|
||||
.push_span_label(frame_span, "...leading to this recursive call");
|
||||
diag.span_note(
|
||||
multispan,
|
||||
format!("which leads to this {}", tcx.def_descr(frame_def_id)),
|
||||
);
|
||||
}
|
||||
}
|
||||
// FIXME: We could report a structured suggestion if we had
|
||||
// enough info here... Maybe we can use a hacky HIR walker.
|
||||
if matches!(
|
||||
coroutine_kind,
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
|
||||
) {
|
||||
diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
|
||||
}
|
||||
|
||||
ControlFlow::Break(diag)
|
||||
fn layout_of<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle_error: CycleError,
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Result<TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
|
||||
let diag = search_for_cycle_permutation(
|
||||
&cycle_error.cycle,
|
||||
|cycle| {
|
||||
if cycle[0].frame.dep_kind == DepKind::layout_of
|
||||
&& let Some(def_id) = cycle[0].frame.def_id_for_ty_in_cycle
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& let def_kind = tcx.def_kind(def_id)
|
||||
&& matches!(def_kind, DefKind::Closure)
|
||||
&& let Some(coroutine_kind) = tcx.coroutine_kind(def_id)
|
||||
{
|
||||
// FIXME: `def_span` for an fn-like coroutine will point to the fn's body
|
||||
// due to interactions between the desugaring into a closure expr and the
|
||||
// def_span code. I'm not motivated to fix it, because I tried and it was
|
||||
// not working, so just hack around it by grabbing the parent fn's span.
|
||||
let span = if coroutine_kind.is_fn_like() {
|
||||
tcx.def_span(tcx.local_parent(def_id))
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
tcx.def_span(def_id)
|
||||
};
|
||||
let mut diag = struct_span_code_err!(
|
||||
tcx.sess.dcx(),
|
||||
span,
|
||||
E0733,
|
||||
"recursion in {} {} requires boxing",
|
||||
tcx.def_kind_descr_article(def_kind, def_id.to_def_id()),
|
||||
tcx.def_kind_descr(def_kind, def_id.to_def_id()),
|
||||
);
|
||||
for (i, info) in cycle.iter().enumerate() {
|
||||
if info.frame.dep_kind != DepKind::layout_of {
|
||||
continue;
|
||||
}
|
||||
let Some(frame_def_id) = info.frame.def_id_for_ty_in_cycle else {
|
||||
continue;
|
||||
};
|
||||
let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else {
|
||||
continue;
|
||||
};
|
||||
let frame_span =
|
||||
info.frame.info.default_span(cycle[(i + 1) % cycle.len()].span);
|
||||
if frame_span.is_dummy() {
|
||||
continue;
|
||||
}
|
||||
if i == 0 {
|
||||
diag.span_label(frame_span, "recursive call here");
|
||||
} else {
|
||||
let coroutine_span: Span = if frame_coroutine_kind.is_fn_like() {
|
||||
tcx.def_span(tcx.parent(frame_def_id))
|
||||
} else {
|
||||
tcx.def_span(frame_def_id)
|
||||
};
|
||||
let mut multispan = MultiSpan::from_span(coroutine_span);
|
||||
multispan.push_span_label(frame_span, "...leading to this recursive call");
|
||||
diag.span_note(
|
||||
multispan,
|
||||
format!("which leads to this {}", tcx.def_descr(frame_def_id)),
|
||||
);
|
||||
}
|
||||
}
|
||||
// FIXME: We could report a structured suggestion if we had
|
||||
// enough info here... Maybe we can use a hacky HIR walker.
|
||||
if matches!(
|
||||
coroutine_kind,
|
||||
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
|
||||
) {
|
||||
diag.note("a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future");
|
||||
}
|
||||
},
|
||||
|| report_cycle(tcx.sess, &cycle_error),
|
||||
);
|
||||
|
||||
let guar = diag.emit();
|
||||
Err(tcx.arena.alloc(LayoutError::Cycle(guar)))
|
||||
}
|
||||
ControlFlow::Break(diag)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
},
|
||||
|| report_cycle(tcx.sess, &cycle_error),
|
||||
);
|
||||
|
||||
let guar = diag.emit();
|
||||
Err(tcx.arena.alloc(LayoutError::Cycle(guar)))
|
||||
}
|
||||
|
||||
// item_and_field_ids should form a cycle where each field contains the
|
||||
// type in the next element in the list
|
||||
|
||||
Reference in New Issue
Block a user