From 7487bdccc328b1714de2ab9b9fbe66fb4174972f Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 14 Jun 2023 10:24:50 -0400 Subject: [PATCH] tamer: nir::air: Recoverable error instead of panic for TODO tokens Now that the feature flag for the parser is a command line option, it is useful to be able to run it on any package and see what errors arise, to use as a guide for development with the goal of getting a particular package to compile. This converts the TODO panic into a recoverable error so that the parser can spit out as many errors as it can. DEV-13162 --- tamer/src/nir/air.rs | 47 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/tamer/src/nir/air.rs b/tamer/src/nir/air.rs index 422ba433..a86f9bf4 100644 --- a/tamer/src/nir/air.rs +++ b/tamer/src/nir/air.rs @@ -299,13 +299,25 @@ impl ParseState for NirToAir { // thing producing NIR. (st @ Meta(..), tok @ Import(_)) => Transition(st).dead(tok), - (_, tok @ (Todo(..) | TodoAttr(..))) => { - crate::diagnostic_todo!( - vec![tok.internal_error( - "this token is not yet supported in TAMER" - )], - "unsupported token: {tok}", - ) + // Unsupported tokens yield errors. + // There _is_ a risk that this will put us in a wildly + // inconsistent state, + // yielding nonsense errors in the future. + // This used to panic, + // but yielding errors allows compilation to continue and + // discover further problems, + // so that this new parser can be run on a given package + // (with e.g. `--emit xmlo-experimental`) + // to get some idea of what type of missing features may + // be needed to support the compilation of that package. + // Note also that, + // at the time of writing, + // large numbers of diagnostic spans may be quite slow to + // output on large files because the system does not cache + // newline locations and requires re-calculating from the + // beginning of the file for earlier spans. + (st, tok @ (Todo(..) | TodoAttr(..))) => { + Transition(st).err(NirToAirError::UnsupportedToken(tok)) } (st, Noop(_)) => Transition(st).incomplete(), @@ -319,6 +331,14 @@ impl ParseState for NirToAir { #[derive(Debug, PartialEq, Eq)] pub enum NirToAirError { + /// The provided token is not yet supported by TAMER. + /// + /// This means that a token was recognized by NIR but it makes no + /// guarantees about _whether_ a token will be supported in the + /// future; + /// explicit rejection is still a future possibility. + UnsupportedToken(Nir), + /// Expected a match subject, /// but encountered some other token. /// @@ -340,6 +360,10 @@ impl Display for NirToAirError { use NirToAirError::*; match self { + UnsupportedToken(tok) => { + write!(f, "unsupported token: {tok}") + } + MatchSubjectExpected(_, nir) => { write!(f, "expected match subject, found {nir}") } @@ -367,6 +391,15 @@ impl Diagnostic for NirToAirError { use NirToAirError::*; match self { + UnsupportedToken(tok) => vec![ + tok.span().internal_error("this token is not yet supported in TAMER"), + tok.span().help( + "if this is unexpected, \ + are you unintentionally using the `--emit xmlo-experimental` \ + command line option?" + ), + ], + MatchSubjectExpected(ospan, given) => vec![ ospan.note("for this match"), given