Skip to content

Filter std::rt::lang_start from graphs#119

Open
dkcumming wants to merge 9 commits intomasterfrom
dc/remove-lang-start
Open

Filter std::rt::lang_start from graphs#119
dkcumming wants to merge 9 commits intomasterfrom
dc/remove-lang-start

Conversation

@dkcumming
Copy link
Collaborator

@dkcumming dkcumming commented Feb 18, 2026

This PR allows us to set a SKIP_LANG_START=1 env var to remove the std::rt::lang_start items from the graph output. Perhaps sometimes they are useful, but I have not ever needed to look at them and would prefer them to be removed from the graph.

I had a bit of trouble getting the correct items for the BFS and I used claude to help for full disclosure, however I have vetted the code and agree with it. Also the output has been tested and it does remove the items correctly. I will post before and after of a contrived program that contains black_box to show that the algorithm will only remove items exclusively downstream of std::rt::lang_start.

fn main() {
    let x = std::hint::black_box(42);
    std::hint::black_box(x);
}

Before

image

After

image

Copy link
Collaborator

@cds-amal cds-amal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nice @dkcumming, I love the story in your commits. I feel strongly about including a test to surface regressions, as I expect there are many more features to come.

There are no integration or unit tests for the SKIP_LANG_START behavior. The existing .smir.json.expected files all contain lang_start items, so there's good data to work from. At minimum, an integration test that runs with SKIP_LANG_START=1 and verifies the output lacks lang_start entries would give confidence this doesn't regress.

dkcumming and others added 7 commits March 4, 2026 23:22
This filters out all `lang_start` items (functions, closures, drop glue
etc.). It only removes the items if they are `std::rt::lang_start` or
are exclusively reachable by those functions. That means `black_box` is
removed if it is not called otherwise in the program, but if it is then
it is not removed. There is a couple of stages to get the data together
in the right form so that only the items desired to be removed are.
Introduces an extensible ItemFilter enum so future exclusion predicates
can be added by just adding a variant, wiring its env var in enabled(),
and implementing compute_exclusions.

The key behavioral change: apply_all() now prunes ctx.functions in
addition to items, so ctx.resolve_call_target() returns None for
excluded callees. This eliminates the need to thread an `excluded` set
through every render function; both dot and d2 renderers are simplified.
Adds a `make test-skip-lang-start` target that runs every test program
through the D2 renderer with SKIP_LANG_START=1 and verifies the output
contains no lang_start references. Catches regressions in the ItemFilter
pipeline without needing separate golden files.
…ring

Replace if-let + early-return with match expression in filter_map,
use matches! macro for single-arm boolean match, and switch enabled()
from imperative push to declarative array-of-options pattern.
@cds-amal cds-amal force-pushed the dc/remove-lang-start branch from 645bbd4 to 474f0b7 Compare March 5, 2026 04:43
@cds-amal cds-amal requested a review from a team March 5, 2026 04:43
cds-amal added 2 commits March 5, 2026 09:24
The integration test now validates at the data-structure level instead
of grepping rendered output. When ASSERT_FILTER=1 is set alongside
SKIP_LANG_START=1, apply_all() asserts two things:

1. The filter's exclusion set is non-empty (precondition: lang_start
   items were present to begin with).
2. No matching items survive in the filtered output (postcondition:
   the filter actually worked).

The precondition check is pedantically complete: std::rt::lang_start is
the runtime wrapper rustc generates for every crate with a fn main, so
it will always appear in monomorphized output. Every one of the 29 test
programs has a main function and every expected output contains exactly
11 lang_start references. It would take a fundamental change to rustc's
runtime initialization for this to stop being true; but if it does, the
assertion will tell us the test data is stale rather than silently
passing.

The more realistic failure mode: someone adds a library crate (no main)
to the test suite. The assert message spells this out and gives two
actionable options (skip lib crates in the test target, or gate the
filter on the presence of main).
echo's treatment of \n is shell-dependent (bash interprets it by
default, zsh and POSIX sh do not without -e). Switch report() and
the failure summary to printf in both integration-test and
test-skip-lang-start targets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants