Final Words

Heuris­tic com­piler diag­nos­tics can­not always local­ize type class errors; inter­ac­tive visu­al­iza­tion of type class res­o­lu­tion is fea­si­ble and with few inter­ac­tions facil­i­tates local­iza­tion. In we talked about the reduc­tive nature of com­piler diag­nos­tics. Type class res­o­lu­tion is a com­plex process. In most com­pil­ers it is black-box to devel­op­ers, thus the curt response “No” is a frus­trat­ing and hard-to-debug expe­ri­ence. Com­pil­ers may use the words “bounds unsat­is­fied,” or “failed to syn­the­size instance” but they can carry the same empti­ness as a “No.” Instead of reduc­ing inter­nal fail­ures to a sin­gle diag­nos­tic, why not give devel­op­ers an inter­face by which they can explore the prob­lem?

intro­duced our first attempt at a solu­tion to this prob­lem. How can we give devel­op­ers the right tools to facil­i­tate debug­ging? First they need the data. Diag­nos­tics often remove this data—we keep it. Sec­ond they need an inter­face. Diag­nos­tics pro­duce a sta­tic file, much like this PDF doc­u­ment, that’s not much of an inter­face. We built an inter­ac­tive debug­ger into the pop­u­lar VSCode edi­tor, we even took this a step fur­ther and built an MdBook plu­gin for Argus.

Visu­al­iza­tion comes with inher­ent prob­lems. Inter­faces get visu­ally clut­tered, they’re con­fus­ing to use, and often­times too much data can be a bad thing. Espe­cially if that data is leak­ing parts of the Rust com­piler inter­nals. Argus uses some sim­ple heuris­tics to pro­vide debug­ging entry­points to devel­op­ers. On 80% of our com­mu­nity curated tests these heuris­tics served the root cause within the first ten items. Ten may seem like a lot, and indeed there’s plenty of room for improve­ment, but often doc­u­men­ta­tion pages con­tain dozens of items. Not to men­tion the two or three pages of doc­u­men­ta­tion of required read­ing before the root cause becomes appar­ent.

Most researchers would title this a “con­clu­sion,” but it’s more of an extended aside. The inten­tion was for it to be a dis­cus­sion, but the frag­ile web of cross-ref­er­ences did not allow for the already exist­ing “dis­cus­sion” file to be renamed. Some of the most excit­ing, frus­trat­ing, and inter­est­ing pieces of research are not the stuffy words in the text, but rather the soft­ware around it. The process. The ref­er­ence struc­ture around these source files is so frag­ile because the author­ing soft­ware used to write the the­sis was built while writ­ing the the­sis. Turns out this is like build­ing a For­mula 1 car mid-grand prix.

The goal was always to have a web ver­sion of the the­sis, but it turns out uni­ver­si­ties appre­ci­ate a PDF. Well—they require one. The solu­tion was to cre­ate a cus­tom markup lan­guage to write the the­sis and accom­mo­date both out­put for­mats. This require­ment com­pounded with haste and inex­pe­ri­ence resulted in a funky lan­guage. Dynamic scop­ing? Check. Inter­faces? Why yes. Macros? Of course. Ulti­mately this was a stress­ful but highly reward­ing process result­ing in a lan­guage no one should ever use again.

Many projects have a dif­fi­cult tech­ni­cal bit that no one cares about. You can shout I spent months work­ing out the details! Yet it receives lit­tle inter­est from advi­sors or peers. The unsung hero of this story is pretty print­ing. con­tains a loose archi­tec­ture dia­gram of Argus. The mod­ule argus::serialize gets its own box for good rea­son. This mod­ule con­tains code to seri­al­ize the entirety of Rust’s type sys­tem, tak­ing heavy inspi­ra­tion from the rustc_middle::ty::print::pretty mod­ule. If pretty print­ing doesn’t seem dif­fi­cult, just count the num­ber of TODO, FIXME, and “uhhh, is this right?” com­ments in the Rust pretty print­ing source code. The chal­lenge was worth it. We can now seri­al­ize Rust types to JSON and play around with them in Argus.

This work has many pos­si­ble exten­sions, and have been out­lined in , , and . The future for Argus is hope­fully upward, and com­ing to an IDE near you.