tamer: Newtypes for all Infallible ParseState errors
More information will be presented in the commit that follows to generalize these, but this sets the stage. The recently-introduced pipeline macro takes care of most of the job of a declarative pipeline, but it's still leaky, since it requires that the _caller_ create error sum types. This not only exposes implementation details and so undermines the goal of making pipelines easy to declare and compose, but it's also one of the last major components of boilerplate for the lowering pipeline. My previous attempts at generating error sum types automatically for pipelines ran into a problem because of overlapping `impl`s for the various `<S as ParseState>::Error` types; this resolves that issue via newtypes. I had considered other approaches, including explicitly generating code to `map_err` as part of the lowering pipeline, but in the end this is the easier way to reason about things that also keeps manual `Lower` pipelines on the same level of expressiveness as the pipeline macro; I want to restrict its unique capabilities as much as possible to elimination of boilerplate and nothing more. DEV-13162main
parent
672cc54c14
commit
1bb25b05b3
|
@ -54,7 +54,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use std::{convert::Infallible, fmt::Display, marker::PhantomData};
|
use std::{fmt::Display, marker::PhantomData};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum AsgTreeToXirf<'a> {
|
pub enum AsgTreeToXirf<'a> {
|
||||||
|
@ -75,10 +75,14 @@ impl<'a> Display for AsgTreeToXirf<'a> {
|
||||||
|
|
||||||
type Xirf = XirfToken<Text>;
|
type Xirf = XirfToken<Text>;
|
||||||
|
|
||||||
|
diagnostic_infallible! {
|
||||||
|
pub enum AsgTreeToXirfError {}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ParseState for AsgTreeToXirf<'a> {
|
impl<'a> ParseState for AsgTreeToXirf<'a> {
|
||||||
type Token = TreeWalkRel;
|
type Token = TreeWalkRel;
|
||||||
type Object = Xirf;
|
type Object = Xirf;
|
||||||
type Error = Infallible;
|
type Error = AsgTreeToXirfError;
|
||||||
type Context = TreeContext<'a>;
|
type Context = TreeContext<'a>;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
|
|
|
@ -74,7 +74,7 @@ pub use graph::{
|
||||||
ObjectKind,
|
ObjectKind,
|
||||||
},
|
},
|
||||||
visit,
|
visit,
|
||||||
xmli::AsgTreeToXirf,
|
xmli::{AsgTreeToXirf, AsgTreeToXirfError},
|
||||||
Asg, AsgResult, IndexType,
|
Asg, AsgResult, IndexType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,21 @@ use std::{
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
use tamer::{
|
use tamer::{
|
||||||
asg::{air::Air, AsgError, DefaultAsg},
|
asg::{
|
||||||
|
air::Air, visit::TreeWalkRel, AsgError, AsgTreeToXirfError, DefaultAsg,
|
||||||
|
},
|
||||||
diagnose::{
|
diagnose::{
|
||||||
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
|
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
|
||||||
},
|
},
|
||||||
nir::{InterpError, Nir, NirToAirError, XirfToNirError},
|
nir::{
|
||||||
|
InterpError, Nir, NirToAirError, TplShortDesugarError, XirfToNirError,
|
||||||
|
},
|
||||||
parse::{lowerable, FinalizeError, ParseError, Token, UnknownToken},
|
parse::{lowerable, FinalizeError, ParseError, Token, UnknownToken},
|
||||||
pipeline::parse_package_xml,
|
pipeline::parse_package_xml,
|
||||||
xir::{
|
xir::{
|
||||||
self,
|
self,
|
||||||
flat::{RefinedText, XirToXirfError, XirfToken},
|
autoclose::XirfAutoCloseError,
|
||||||
|
flat::{RefinedText, Text, XirToXirfError, XirfToXirError, XirfToken},
|
||||||
reader::XmlXirReader,
|
reader::XmlXirReader,
|
||||||
DefaultEscaper, Token as XirToken,
|
DefaultEscaper, Token as XirToken,
|
||||||
},
|
},
|
||||||
|
@ -317,6 +322,9 @@ pub enum UnrecoverableError {
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
Fmt(fmt::Error),
|
Fmt(fmt::Error),
|
||||||
XirWriterError(xir::writer::Error),
|
XirWriterError(xir::writer::Error),
|
||||||
|
AsgTreeToXirfError(ParseError<TreeWalkRel, AsgTreeToXirfError>),
|
||||||
|
XirfAutoCloseError(ParseError<XirfToken<Text>, XirfAutoCloseError>),
|
||||||
|
XirfToXirError(ParseError<XirfToken<Text>, XirfToXirError>),
|
||||||
ErrorsDuringLowering(ErrorCount),
|
ErrorsDuringLowering(ErrorCount),
|
||||||
FinalizeError(FinalizeError),
|
FinalizeError(FinalizeError),
|
||||||
}
|
}
|
||||||
|
@ -353,6 +361,7 @@ pub enum RecoverableError {
|
||||||
XirParseError(ParseError<UnknownToken, xir::Error>),
|
XirParseError(ParseError<UnknownToken, xir::Error>),
|
||||||
XirfParseError(ParseError<XirToken, XirToXirfError>),
|
XirfParseError(ParseError<XirToken, XirToXirfError>),
|
||||||
NirParseError(ParseError<XirfToken<RefinedText>, XirfToNirError>),
|
NirParseError(ParseError<XirfToken<RefinedText>, XirfToNirError>),
|
||||||
|
TplShortDesugarError(ParseError<Nir, TplShortDesugarError>),
|
||||||
InterpError(ParseError<Nir, InterpError>),
|
InterpError(ParseError<Nir, InterpError>),
|
||||||
NirToAirError(ParseError<Nir, NirToAirError>),
|
NirToAirError(ParseError<Nir, NirToAirError>),
|
||||||
AirAggregateError(ParseError<Air, AsgError>),
|
AirAggregateError(ParseError<Air, AsgError>),
|
||||||
|
@ -376,15 +385,29 @@ impl From<xir::writer::Error> for UnrecoverableError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FinalizeError> for UnrecoverableError {
|
impl From<ParseError<TreeWalkRel, AsgTreeToXirfError>> for UnrecoverableError {
|
||||||
fn from(e: FinalizeError) -> Self {
|
fn from(e: ParseError<TreeWalkRel, AsgTreeToXirfError>) -> Self {
|
||||||
Self::FinalizeError(e)
|
Self::AsgTreeToXirfError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Infallible> for UnrecoverableError {
|
impl From<ParseError<XirfToken<Text>, XirfToXirError>> for UnrecoverableError {
|
||||||
fn from(_: Infallible) -> Self {
|
fn from(e: ParseError<XirfToken<Text>, XirfToXirError>) -> Self {
|
||||||
unreachable!("<UnrecoverableError as From<Infallible>>::from")
|
Self::XirfToXirError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseError<XirfToken<Text>, XirfAutoCloseError>>
|
||||||
|
for UnrecoverableError
|
||||||
|
{
|
||||||
|
fn from(e: ParseError<XirfToken<Text>, XirfAutoCloseError>) -> Self {
|
||||||
|
Self::XirfAutoCloseError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FinalizeError> for UnrecoverableError {
|
||||||
|
fn from(e: FinalizeError) -> Self {
|
||||||
|
Self::FinalizeError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,14 +419,6 @@ impl<T: Token> From<ParseError<T, Infallible>> for UnrecoverableError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Token> From<ParseError<T, Infallible>> for RecoverableError {
|
|
||||||
fn from(_: ParseError<T, Infallible>) -> Self {
|
|
||||||
unreachable!(
|
|
||||||
"<RecoverableError as From<ParseError<T, Infallible>>>::from"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ParseError<UnknownToken, xir::Error>> for RecoverableError {
|
impl From<ParseError<UnknownToken, xir::Error>> for RecoverableError {
|
||||||
fn from(e: ParseError<UnknownToken, xir::Error>) -> Self {
|
fn from(e: ParseError<UnknownToken, xir::Error>) -> Self {
|
||||||
Self::XirParseError(e)
|
Self::XirParseError(e)
|
||||||
|
@ -424,6 +439,12 @@ impl From<ParseError<XirfToken<RefinedText>, XirfToNirError>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ParseError<Nir, TplShortDesugarError>> for RecoverableError {
|
||||||
|
fn from(e: ParseError<Nir, TplShortDesugarError>) -> Self {
|
||||||
|
Self::TplShortDesugarError(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ParseError<Nir, InterpError>> for RecoverableError {
|
impl From<ParseError<Nir, InterpError>> for RecoverableError {
|
||||||
fn from(e: ParseError<Nir, InterpError>) -> Self {
|
fn from(e: ParseError<Nir, InterpError>) -> Self {
|
||||||
Self::InterpError(e)
|
Self::InterpError(e)
|
||||||
|
@ -450,6 +471,9 @@ impl Display for UnrecoverableError {
|
||||||
Io(e) => Display::fmt(e, f),
|
Io(e) => Display::fmt(e, f),
|
||||||
Fmt(e) => Display::fmt(e, f),
|
Fmt(e) => Display::fmt(e, f),
|
||||||
XirWriterError(e) => Display::fmt(e, f),
|
XirWriterError(e) => Display::fmt(e, f),
|
||||||
|
AsgTreeToXirfError(e) => Display::fmt(e, f),
|
||||||
|
XirfToXirError(e) => Display::fmt(e, f),
|
||||||
|
XirfAutoCloseError(e) => Display::fmt(e, f),
|
||||||
FinalizeError(e) => Display::fmt(e, f),
|
FinalizeError(e) => Display::fmt(e, f),
|
||||||
|
|
||||||
// TODO: Use formatter for dynamic "error(s)"
|
// TODO: Use formatter for dynamic "error(s)"
|
||||||
|
@ -468,6 +492,7 @@ impl Display for RecoverableError {
|
||||||
XirParseError(e) => Display::fmt(e, f),
|
XirParseError(e) => Display::fmt(e, f),
|
||||||
XirfParseError(e) => Display::fmt(e, f),
|
XirfParseError(e) => Display::fmt(e, f),
|
||||||
NirParseError(e) => Display::fmt(e, f),
|
NirParseError(e) => Display::fmt(e, f),
|
||||||
|
TplShortDesugarError(e) => Display::fmt(e, f),
|
||||||
InterpError(e) => Display::fmt(e, f),
|
InterpError(e) => Display::fmt(e, f),
|
||||||
NirToAirError(e) => Display::fmt(e, f),
|
NirToAirError(e) => Display::fmt(e, f),
|
||||||
AirAggregateError(e) => Display::fmt(e, f),
|
AirAggregateError(e) => Display::fmt(e, f),
|
||||||
|
@ -475,40 +500,16 @@ impl Display for RecoverableError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for UnrecoverableError {
|
impl Error for UnrecoverableError {}
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
use UnrecoverableError::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
Io(e) => Some(e),
|
|
||||||
Fmt(e) => Some(e),
|
|
||||||
XirWriterError(e) => Some(e),
|
|
||||||
ErrorsDuringLowering(_) => None,
|
|
||||||
FinalizeError(e) => Some(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for RecoverableError {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
use RecoverableError::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
XirParseError(e) => Some(e),
|
|
||||||
XirfParseError(e) => Some(e),
|
|
||||||
NirParseError(e) => Some(e),
|
|
||||||
InterpError(e) => Some(e),
|
|
||||||
NirToAirError(e) => Some(e),
|
|
||||||
AirAggregateError(e) => Some(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Diagnostic for UnrecoverableError {
|
impl Diagnostic for UnrecoverableError {
|
||||||
fn describe(&self) -> Vec<AnnotatedSpan> {
|
fn describe(&self) -> Vec<AnnotatedSpan> {
|
||||||
use UnrecoverableError::*;
|
use UnrecoverableError::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
AsgTreeToXirfError(e) => e.describe(),
|
||||||
|
XirfToXirError(e) => e.describe(),
|
||||||
|
XirfAutoCloseError(e) => e.describe(),
|
||||||
FinalizeError(e) => e.describe(),
|
FinalizeError(e) => e.describe(),
|
||||||
|
|
||||||
// Fall back to `Display`
|
// Fall back to `Display`
|
||||||
|
@ -527,6 +528,7 @@ impl Diagnostic for RecoverableError {
|
||||||
XirParseError(e) => e.describe(),
|
XirParseError(e) => e.describe(),
|
||||||
XirfParseError(e) => e.describe(),
|
XirfParseError(e) => e.describe(),
|
||||||
NirParseError(e) => e.describe(),
|
NirParseError(e) => e.describe(),
|
||||||
|
TplShortDesugarError(e) => e.describe(),
|
||||||
InterpError(e) => e.describe(),
|
InterpError(e) => e.describe(),
|
||||||
NirToAirError(e) => e.describe(),
|
NirToAirError(e) => e.describe(),
|
||||||
AirAggregateError(e) => e.describe(),
|
AirAggregateError(e) => e.describe(),
|
||||||
|
|
|
@ -332,3 +332,55 @@ impl<S: Into<Span>> Annotate for S {
|
||||||
AnnotatedSpan(self.into(), level, label)
|
AnnotatedSpan(self.into(), level, label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a variant-less error enum akin to [`Infallible`].
|
||||||
|
///
|
||||||
|
/// This is used to create [`Infallible`]-like newtypes where unique error
|
||||||
|
/// types are beneficial.
|
||||||
|
/// For example,
|
||||||
|
/// this can be used so that [`From`] implementations can be exclusively
|
||||||
|
/// used to widen errors
|
||||||
|
/// (or lack thereof)
|
||||||
|
/// into error sum variants,
|
||||||
|
/// and is especially useful when code generation is involved to avoid
|
||||||
|
/// generation of overlapping [`From`] `impl`s.
|
||||||
|
///
|
||||||
|
/// The generated enum is convertable [`Into`] and [`From`] [`Infallible`].
|
||||||
|
macro_rules! diagnostic_infallible {
|
||||||
|
($vis:vis enum $name:ident {}) => {
|
||||||
|
/// A unique [`Infallible`](std::convert::Infallible) type.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
$vis enum $name {}
|
||||||
|
|
||||||
|
impl std::fmt::Display for $name {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, stringify!($name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::diagnose::Diagnostic for $name {
|
||||||
|
fn describe(&self) -> Vec<$crate::diagnose::AnnotatedSpan> {
|
||||||
|
// This is a unit struct and should not be able to be
|
||||||
|
// instantiated!
|
||||||
|
unreachable!(
|
||||||
|
concat!(
|
||||||
|
stringify!($name),
|
||||||
|
" should be unreachable!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::convert::Infallible> for $name {
|
||||||
|
fn from(_: std::convert::Infallible) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<$name> for std::convert::Infallible {
|
||||||
|
fn from(_: $name) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -181,12 +181,13 @@ pub mod global;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate static_assertions;
|
extern crate static_assertions;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
pub mod diagnose;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod xir;
|
pub mod xir;
|
||||||
|
|
||||||
pub mod asg;
|
pub mod asg;
|
||||||
pub mod convert;
|
pub mod convert;
|
||||||
pub mod diagnose;
|
|
||||||
pub mod f;
|
pub mod f;
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub use interp::{InterpError, InterpState as InterpolateNir};
|
||||||
pub use parse::{
|
pub use parse::{
|
||||||
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,
|
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,
|
||||||
};
|
};
|
||||||
pub use tplshort::TplShortDesugar;
|
pub use tplshort::{TplShortDesugar, TplShortDesugarError};
|
||||||
|
|
||||||
/// IR that is "near" the source code.
|
/// IR that is "near" the source code.
|
||||||
///
|
///
|
||||||
|
|
|
@ -108,8 +108,6 @@ impl ParseState for NirToAir {
|
||||||
use NirToAir::*;
|
use NirToAir::*;
|
||||||
use NirToAirError::*;
|
use NirToAirError::*;
|
||||||
|
|
||||||
use crate::diagnostic_panic;
|
|
||||||
|
|
||||||
if let Some(obj) = stack.pop() {
|
if let Some(obj) = stack.pop() {
|
||||||
return Transition(Ready).ok(obj).with_lookahead(tok);
|
return Transition(Ready).ok(obj).with_lookahead(tok);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,6 @@ use crate::{
|
||||||
SymbolId,
|
SymbolId,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::convert::Infallible;
|
|
||||||
|
|
||||||
use Nir::*;
|
use Nir::*;
|
||||||
use NirEntity::*;
|
use NirEntity::*;
|
||||||
|
@ -130,10 +129,14 @@ impl Display for TplShortDesugar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diagnostic_infallible! {
|
||||||
|
pub enum TplShortDesugarError {}
|
||||||
|
}
|
||||||
|
|
||||||
impl ParseState for TplShortDesugar {
|
impl ParseState for TplShortDesugar {
|
||||||
type Token = Nir;
|
type Token = Nir;
|
||||||
type Object = Nir;
|
type Object = Nir;
|
||||||
type Error = Infallible;
|
type Error = TplShortDesugarError;
|
||||||
type Context = Stack;
|
type Context = Stack;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
|
|
|
@ -39,6 +39,18 @@
|
||||||
//! The module is responsible for pipeline composition.
|
//! The module is responsible for pipeline composition.
|
||||||
//! For information on the lowering pipeline as an abstraction,
|
//! For information on the lowering pipeline as an abstraction,
|
||||||
//! see [`Lower`].
|
//! see [`Lower`].
|
||||||
|
//!
|
||||||
|
//! Error Widening
|
||||||
|
//! ==============
|
||||||
|
//! Each [`ParseState`] in the pipeline is expected to have its own unique
|
||||||
|
//! error type,
|
||||||
|
//! utilizing newtypes if necessary;
|
||||||
|
//! this ensures that errors are able to be uniquely paired with each
|
||||||
|
//! [`ParseState`] that produced it without having to perform an
|
||||||
|
//! explicit mapping at the call site.
|
||||||
|
//! To facilitate that automatic mapping/aggregation,
|
||||||
|
//! this uniqueness property also allows for generation of [`From`]
|
||||||
|
//! implementations that will not overlap.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
asg::{air::AirAggregate, AsgTreeToXirf},
|
asg::{air::AirAggregate, AsgTreeToXirf},
|
||||||
|
|
|
@ -106,7 +106,7 @@ use crate::{
|
||||||
span::{Span, UNKNOWN_SPAN},
|
span::{Span, UNKNOWN_SPAN},
|
||||||
xir::EleSpan,
|
xir::EleSpan,
|
||||||
};
|
};
|
||||||
use std::{convert::Infallible, fmt::Display};
|
use std::fmt::Display;
|
||||||
|
|
||||||
use XirfAutoClose::*;
|
use XirfAutoClose::*;
|
||||||
|
|
||||||
|
@ -138,10 +138,14 @@ impl Display for XirfAutoClose {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diagnostic_infallible! {
|
||||||
|
pub enum XirfAutoCloseError {}
|
||||||
|
}
|
||||||
|
|
||||||
impl ParseState for XirfAutoClose {
|
impl ParseState for XirfAutoClose {
|
||||||
type Token = XirfToken<Text>;
|
type Token = XirfToken<Text>;
|
||||||
type Object = XirfToken<Text>;
|
type Object = XirfToken<Text>;
|
||||||
type Error = Infallible;
|
type Error = XirfAutoCloseError;
|
||||||
type Context = AutoCloseStack;
|
type Context = AutoCloseStack;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
|
|
|
@ -55,7 +55,6 @@ use crate::{
|
||||||
};
|
};
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use std::{
|
use std::{
|
||||||
convert::Infallible,
|
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
@ -926,10 +925,14 @@ impl<T: TextType> Display for XirfToXir<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diagnostic_infallible! {
|
||||||
|
pub enum XirfToXirError {}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: TextType> ParseState for XirfToXir<T> {
|
impl<T: TextType> ParseState for XirfToXir<T> {
|
||||||
type Token = XirfToken<T>;
|
type Token = XirfToken<T>;
|
||||||
type Object = XirToken;
|
type Object = XirToken;
|
||||||
type Error = Infallible;
|
type Error = XirfToXirError;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -619,10 +619,10 @@ fn xirf_to_xir() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// The lowering pipeline above requires compatible errors.
|
// The lowering pipeline above requires compatible errors.
|
||||||
impl From<ParseError<XirfToken<Text>, Infallible>>
|
impl From<ParseError<XirfToken<Text>, XirfToXirError>>
|
||||||
for ParseError<XirToken, XirToXirfError>
|
for ParseError<XirToken, XirToXirfError>
|
||||||
{
|
{
|
||||||
fn from(_value: ParseError<XirfToken<Text>, Infallible>) -> Self {
|
fn from(_value: ParseError<XirfToken<Text>, XirfToXirError>) -> Self {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue