DummyAstNode for crate::ast_traits::AstNo
#[derive(Debug)]
pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
- Fn(
- FnCtxt,
- &'a mut Ident,
- &'a mut FnSig,
- &'a mut Visibility,
- &'a mut Generics,
- &'a mut Option>,
- ),
+ Fn(FnCtxt, &'a mut Ident, &'a mut Visibility, &'a mut Fn),
/// E.g., `|x, y| body`.
Closure(
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 3b7367d1ee20..100f664a89fd 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -527,13 +527,13 @@ impl TokenKind {
/// Returns tokens that are likely to be typed accidentally instead of the current token.
/// Enables better error recovery when the wrong token is found.
- pub fn similar_tokens(&self) -> Option> {
- match *self {
- Comma => Some(vec![Dot, Lt, Semi]),
- Semi => Some(vec![Colon, Comma]),
- Colon => Some(vec![Semi]),
- FatArrow => Some(vec![Eq, RArrow, Ge, Gt]),
- _ => None,
+ pub fn similar_tokens(&self) -> &[TokenKind] {
+ match self {
+ Comma => &[Dot, Lt, Semi],
+ Semi => &[Colon, Comma],
+ Colon => &[Semi],
+ FatArrow => &[Eq, RArrow, Ge, Gt],
+ _ => &[],
}
}
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1d6d7330757d..232fd546de9a 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -65,7 +65,7 @@ impl BoundKind {
#[derive(Copy, Clone, Debug)]
pub enum FnKind<'a> {
/// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
- Fn(FnCtxt, &'a Ident, &'a FnSig, &'a Visibility, &'a Generics, &'a Option>),
+ Fn(FnCtxt, &'a Ident, &'a Visibility, &'a Fn),
/// E.g., `|x, y| body`.
Closure(&'a ClosureBinder, &'a Option, &'a FnDecl, &'a Expr),
@@ -74,7 +74,7 @@ pub enum FnKind<'a> {
impl<'a> FnKind<'a> {
pub fn header(&self) -> Option<&'a FnHeader> {
match *self {
- FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header),
+ FnKind::Fn(_, _, _, Fn { sig, .. }) => Some(&sig.header),
FnKind::Closure(..) => None,
}
}
@@ -88,7 +88,7 @@ impl<'a> FnKind<'a> {
pub fn decl(&self) -> &'a FnDecl {
match self {
- FnKind::Fn(_, _, sig, _, _, _) => &sig.decl,
+ FnKind::Fn(_, _, _, Fn { sig, .. }) => &sig.decl,
FnKind::Closure(_, _, decl, _) => decl,
}
}
@@ -374,8 +374,8 @@ impl WalkItemKind for ItemKind {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
- ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
- let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body);
+ ItemKind::Fn(func) => {
+ let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
ItemKind::Mod(_unsafety, mod_kind) => match mod_kind {
@@ -715,8 +715,8 @@ impl WalkItemKind for ForeignItemKind {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
- ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
- let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body);
+ ForeignItemKind::Fn(func) => {
+ let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
ForeignItemKind::TyAlias(box TyAlias {
@@ -858,7 +858,12 @@ pub fn walk_fn_decl<'a, V: Visitor<'a>>(
pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result {
match kind {
- FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => {
+ FnKind::Fn(
+ _ctxt,
+ _ident,
+ _vis,
+ Fn { defaultness: _, sig: FnSig { header, decl, span: _ }, generics, body },
+ ) => {
// Identifier and visibility are visited as a part of the item.
try_visit!(visitor.visit_fn_header(header));
try_visit!(visitor.visit_generics(generics));
@@ -892,8 +897,8 @@ impl WalkItemKind for AssocItemKind {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
}
- AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
- let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body);
+ AssocItemKind::Fn(func) => {
+ let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
AssocItemKind::Type(box TyAlias {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index f31e2c65c792..1267281f73eb 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1391,7 +1391,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
None,
);
// Destructure like a unit struct.
- let unit_struct_pat = hir::PatKind::Path(qpath);
+ let unit_struct_pat = hir::PatKind::Expr(self.arena.alloc(hir::PatExpr {
+ kind: hir::PatExprKind::Path(qpath),
+ hir_id: self.next_id(),
+ span: self.lower_span(lhs.span),
+ }));
return self.pat_without_dbm(lhs.span, unit_struct_pat);
}
}
@@ -2125,7 +2129,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.arena.alloc(self.expr_call_mut(span, e, args))
}
- fn expr_call_lang_item_fn_mut(
+ pub(super) fn expr_call_lang_item_fn_mut(
&mut self,
span: Span,
lang_item: hir::LangItem,
@@ -2135,7 +2139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.expr_call_mut(span, path, args)
}
- fn expr_call_lang_item_fn(
+ pub(super) fn expr_call_lang_item_fn(
&mut self,
span: Span,
lang_item: hir::LangItem,
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 3c78ed0497d7..cde8ddbfe03c 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -69,7 +69,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
- break hir::PatKind::Path(qpath);
+ let kind = hir::PatExprKind::Path(qpath);
+ let span = self.lower_span(pattern.span);
+ let expr = hir::PatExpr { hir_id: pat_hir_id, span, kind };
+ let expr = self.arena.alloc(expr);
+ return hir::Pat {
+ hir_id: self.next_id(),
+ kind: hir::PatKind::Expr(expr),
+ span,
+ default_binding_modes: true,
+ };
}
PatKind::Struct(qself, path, fields, etc) => {
let qpath = self.lower_qpath(
@@ -304,16 +313,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
Some(res) => {
- let hir_id = self.next_id();
let res = self.lower_res(res);
- hir::PatKind::Path(hir::QPath::Resolved(
- None,
- self.arena.alloc(hir::Path {
- span: self.lower_span(ident.span),
- res,
- segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
- }),
- ))
+ let span = self.lower_span(ident.span);
+ hir::PatKind::Expr(self.arena.alloc(hir::PatExpr {
+ kind: hir::PatExprKind::Path(hir::QPath::Resolved(
+ None,
+ self.arena.alloc(hir::Path {
+ span,
+ res,
+ segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), self.next_id(), res)],
+ }),
+ )),
+ hir_id: self.next_id(),
+ span,
+ }))
}
}
}
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 236ca7ba7035..ea1f4a6559ac 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -917,7 +917,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
}
- ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => {
+ ItemKind::Fn(func @ box Fn { defaultness, generics: _, sig, body }) => {
self.check_defaultness(item.span, *defaultness);
let is_intrinsic =
@@ -947,7 +947,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
- let kind = FnKind::Fn(FnCtxt::Free, &item.ident, sig, &item.vis, generics, body);
+ let kind = FnKind::Fn(FnCtxt::Free, &item.ident, &item.vis, &*func);
self.visit_fn(kind, item.span, item.id);
walk_list!(self, visit_attribute, &item.attrs);
return; // Avoid visiting again.
@@ -1348,19 +1348,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
if let FnKind::Fn(
- _,
- _,
- FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
_,
_,
_,
+ Fn {
+ sig: FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
+ ..
+ },
) = fk
{
self.maybe_lint_missing_abi(*extern_span, id);
}
// Functions without bodies cannot have patterns.
- if let FnKind::Fn(ctxt, _, sig, _, _, None) = fk {
+ if let FnKind::Fn(ctxt, _, _, Fn { body: None, sig, .. }) = fk {
Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| {
if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) {
if let Some(ident) = ident {
@@ -1394,7 +1395,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.is_some();
let disallowed = (!tilde_const_allowed).then(|| match fk {
- FnKind::Fn(_, ident, _, _, _, _) => TildeConstReason::Function { ident: ident.span },
+ FnKind::Fn(_, ident, _, _) => TildeConstReason::Function { ident: ident.span },
FnKind::Closure(..) => TildeConstReason::Closure,
});
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
@@ -1470,15 +1471,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.outer_trait_or_trait_impl.as_ref().and_then(TraitOrTraitImpl::constness).is_some();
match &item.kind {
- AssocItemKind::Fn(box Fn { sig, generics, body, .. })
+ AssocItemKind::Fn(func)
if parent_is_const
|| ctxt == AssocCtxt::Trait
- || matches!(sig.header.constness, Const::Yes(_)) =>
+ || matches!(func.sig.header.constness, Const::Yes(_)) =>
{
self.visit_vis(&item.vis);
self.visit_ident(&item.ident);
- let kind =
- FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, sig, &item.vis, generics, body);
+ let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, &item.vis, &*func);
walk_list!(self, visit_attribute, &item.attrs);
self.visit_fn(kind, item.span, item.id);
}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 897c275d850c..4cfcaa95233d 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -34,8 +34,8 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
- ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
- self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
+ ast::ForeignItemKind::Fn(func) => {
+ self.print_fn_full(ident, vis, attrs, &*func);
}
ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => {
self.print_item_const(
@@ -199,16 +199,8 @@ impl<'a> State<'a> {
*defaultness,
);
}
- ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
- self.print_fn_full(
- sig,
- item.ident,
- generics,
- &item.vis,
- *defaultness,
- body.as_deref(),
- &item.attrs,
- );
+ ast::ItemKind::Fn(func) => {
+ self.print_fn_full(item.ident, &item.vis, &item.attrs, &*func);
}
ast::ItemKind::Mod(safety, mod_kind) => {
self.head(Self::to_string(|s| {
@@ -542,8 +534,8 @@ impl<'a> State<'a> {
self.maybe_print_comment(span.lo());
self.print_outer_attributes(attrs);
match kind {
- ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
- self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
+ ast::AssocItemKind::Fn(func) => {
+ self.print_fn_full(ident, vis, attrs, &*func);
}
ast::AssocItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
self.print_item_const(
@@ -653,19 +645,17 @@ impl<'a> State<'a> {
fn print_fn_full(
&mut self,
- sig: &ast::FnSig,
name: Ident,
- generics: &ast::Generics,
vis: &ast::Visibility,
- defaultness: ast::Defaultness,
- body: Option<&ast::Block>,
attrs: &[ast::Attribute],
+ func: &ast::Fn,
) {
+ let ast::Fn { defaultness, generics, sig, body } = func;
if body.is_some() {
self.head("");
}
self.print_visibility(vis);
- self.print_defaultness(defaultness);
+ self.print_defaultness(*defaultness);
self.print_fn(&sig.decl, sig.header, Some(name), generics);
if let Some(body) = body {
self.nbsp();
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index 90d12ea83285..475897d8f3e3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx);
- type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
+ type_op_ascribe_user_type_with_span(&ocx, key, cause.span).ok()?;
let diag = try_extract_error_from_fulfill_cx(
&ocx,
mbcx.mir_def_id(),
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 07dcbba019ad..0118b72962de 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -3777,7 +3777,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let tcx = self.infcx.tcx;
if let Some(Terminator { kind: TerminatorKind::Call { call_source, fn_span, .. }, .. }) =
&self.body[loan.reserve_location.block].terminator
- && let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
+ && let Some((method_did, method_args)) = mir::find_self_call(
tcx,
self.body,
loan.assigned_place.local,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index bd6f77156ca9..5fe8eef34600 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -17,7 +17,7 @@ use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
- StatementKind, Terminator, TerminatorKind,
+ StatementKind, Terminator, TerminatorKind, find_self_call,
};
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -1016,12 +1016,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
kind: TerminatorKind::Call { fn_span, call_source, .. }, ..
}) = &self.body[location.block].terminator
{
- let Some((method_did, method_args)) = rustc_middle::util::find_self_call(
- self.infcx.tcx,
- self.body,
- target_temp,
- location.block,
- ) else {
+ let Some((method_did, method_args)) =
+ find_self_call(self.infcx.tcx, self.body, target_temp, location.block)
+ else {
return normal_ret;
};
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index a6ca038282d9..e841a5e4c948 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1140,10 +1140,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let amp_mut_sugg = match *local_decl.local_info() {
LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
- let suggestion = suggest_ampmut_self(self.infcx.tcx, decl_span);
- let additional =
- local_trait.map(|span| (span, suggest_ampmut_self(self.infcx.tcx, span)));
- Some(AmpMutSugg { has_sugg: true, span: decl_span, suggestion, additional })
+ let (span, suggestion) = suggest_ampmut_self(self.infcx.tcx, decl_span);
+ let additional = local_trait.map(|span| suggest_ampmut_self(self.infcx.tcx, span));
+ Some(AmpMutSugg { has_sugg: true, span, suggestion, additional })
}
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
@@ -1202,10 +1201,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
opt_ty_info: None,
..
})) => {
- let sugg = suggest_ampmut_self(self.infcx.tcx, decl_span);
+ let (span, sugg) =
+ suggest_ampmut_self(self.infcx.tcx, decl_span);
Some(AmpMutSugg {
has_sugg: true,
- span: decl_span,
+ span,
suggestion: sugg,
additional: None,
})
@@ -1461,17 +1461,12 @@ fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option(tcx: TyCtxt<'tcx>, span: Span) -> String {
+fn suggest_ampmut_self(tcx: TyCtxt<'_>, span: Span) -> (Span, String) {
match tcx.sess.source_map().span_to_snippet(span) {
- Ok(snippet) => {
- let lt_pos = snippet.find('\'');
- if let Some(lt_pos) = lt_pos {
- format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
- } else {
- "&mut self".to_string()
- }
+ Ok(snippet) if snippet.ends_with("self") => {
+ (span.with_hi(span.hi() - BytePos(4)).shrink_to_hi(), "mut ".to_string())
}
- _ => "&mut self".to_string(),
+ _ => (span, "&mut self".to_string()),
}
}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 91dc76f597ad..decfab502bb5 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1284,15 +1284,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
);
}
- &Rvalue::RawPtr(mutability, place) => {
- let access_kind = match mutability {
- Mutability::Mut => (
+ &Rvalue::RawPtr(kind, place) => {
+ let access_kind = match kind {
+ RawPtrKind::Mut => (
Deep,
Write(WriteKind::MutableBorrow(BorrowKind::Mut {
kind: MutBorrowKind::Default,
})),
),
- Mutability::Not => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
+ RawPtrKind::Const => (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))),
+ RawPtrKind::FakeForPtrMetadata => {
+ (Shallow(Some(ArtificialField::ArrayLength)), Read(ReadKind::Copy))
+ }
};
self.access_place(
diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs
index 40e801d03885..6d32ee17f4c2 100644
--- a/compiler/rustc_borrowck/src/polonius/dump.rs
+++ b/compiler/rustc_borrowck/src/polonius/dump.rs
@@ -1,14 +1,20 @@
use std::io;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_index::IndexVec;
use rustc_middle::mir::pretty::{
PassWhere, PrettyPrintMirOptions, create_dump_file, dump_enabled, dump_mir_to_writer,
};
-use rustc_middle::mir::{Body, ClosureRegionRequirements};
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::mir::{Body, ClosureRegionRequirements, Location};
+use rustc_middle::ty::{RegionVid, TyCtxt};
+use rustc_mir_dataflow::points::PointIndex;
use rustc_session::config::MirIncludeSpans;
use crate::borrow_set::BorrowSet;
+use crate::constraints::OutlivesConstraint;
use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
+use crate::region_infer::values::LivenessValues;
+use crate::type_check::Locations;
use crate::{BorrowckInferCtxt, RegionInferenceContext};
/// `-Zdump-mir=polonius` dumps MIR annotated with NLL and polonius specific information.
@@ -50,6 +56,8 @@ pub(crate) fn dump_polonius_mir<'tcx>(
/// - the NLL MIR
/// - the list of polonius localized constraints
/// - a mermaid graph of the CFG
+/// - a mermaid graph of the NLL regions and the constraints between them
+/// - a mermaid graph of the NLL SCCs and the constraints between them
fn emit_polonius_dump<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
@@ -68,25 +76,54 @@ fn emit_polonius_dump<'tcx>(
// Section 1: the NLL + Polonius MIR.
writeln!(out, "")?;
writeln!(out, "Raw MIR dump")?;
- writeln!(out, "
")?;
+ writeln!(out, "")?;
emit_html_mir(
tcx,
body,
regioncx,
borrow_set,
- localized_outlives_constraints,
+ &localized_outlives_constraints,
closure_region_requirements,
out,
)?;
- writeln!(out, "
")?;
+ writeln!(out, "")?;
writeln!(out, "
")?;
- // Section 2: mermaid visualization of the CFG.
+ // Section 2: mermaid visualization of the polonius constraint graph.
+ writeln!(out, "")?;
+ writeln!(out, "Polonius constraint graph")?;
+ writeln!(out, "
")?;
+ let edge_count = emit_mermaid_constraint_graph(
+ borrow_set,
+ regioncx.liveness_constraints(),
+ &localized_outlives_constraints,
+ out,
+ )?;
+ writeln!(out, "
")?;
+ writeln!(out, "
")?;
+
+ // Section 3: mermaid visualization of the CFG.
writeln!(out, "")?;
writeln!(out, "Control-flow graph")?;
- writeln!(out, "
")?;
+ writeln!(out, "")?;
emit_mermaid_cfg(body, out)?;
- writeln!(out, "
")?;
+ writeln!(out, "")?;
+ writeln!(out, "
")?;
+
+ // Section 4: mermaid visualization of the NLL region graph.
+ writeln!(out, "")?;
+ writeln!(out, "NLL regions")?;
+ writeln!(out, "
")?;
+ emit_mermaid_nll_regions(regioncx, out)?;
+ writeln!(out, "
")?;
+ writeln!(out, "
")?;
+
+ // Section 5: mermaid visualization of the NLL SCC graph.
+ writeln!(out, "")?;
+ writeln!(out, "NLL SCCs")?;
+ writeln!(out, "
")?;
+ emit_mermaid_nll_sccs(regioncx, out)?;
+ writeln!(out, "
")?;
writeln!(out, "
")?;
// Finalize the dump with the HTML epilogue.
@@ -95,7 +132,11 @@ fn emit_polonius_dump<'tcx>(
""
)?;
writeln!(out, "")?;
writeln!(out, "