pub fn fold_term_as_type<'t>(&self, term: Spanned<Term<'t>>) -> Result<Spanned<Term<'t>>> {
        let (new, new_term) = match term.value {
            Term::Unresolved(name) => {
                self.emit(DiagBuilder2::error(format!("`{}` is unknown", name)).span(term.span));
                return Err(());
            }
            Term::RangeSuffix(subterm, range) => {
                let subterm = self.fold_term_as_type(*subterm)?;
                let range = self.fold_term_as_type(*range)?;
                match subterm.value {
                    // Fold `TypeMark range T` to `SubtypeInd`.
                    Term::TypeMark(tm) => (true, Term::SubtypeInd(tm, None, Some(Box::new(range)))),
                    // Fold `SubtypeInd range T` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, Some(con)) => {
                        let sp = Span::union(con.span, range.span);
                        let new_con = Spanned::new(Term::RangeSuffix(con, Box::new(range)), sp);
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(new_con))))
                    }
                    _ => (false, Term::RangeSuffix(Box::new(subterm), Box::new(range))),
                }
            }
            Term::SuffixParen(subterm, suffix) => {
                let subterm = self.fold_term_as_type(*subterm)?;
                let suffix = self.fold_term_as_type(*suffix)?;
                match subterm.value {
                    // Fold `TypeMark (T)` to `SubtypeInd`.
                    Term::TypeMark(tm) => {
                        (true, Term::SubtypeInd(tm, None, Some(Box::new(suffix))))
                    }
                    // Fold `SubtypeInd (T)` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, Some(con)) => {
                        let sp = Span::union(con.span, suffix.span);
                        let new_con = Spanned::new(Term::SuffixParen(con, Box::new(suffix)), sp);
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(new_con))))
                    }
                    // Fold `SubtypeInd (T)` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, None) => {
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(suffix))))
                    }
                    _ => (
                        false,
                        Term::SuffixParen(Box::new(subterm), Box::new(suffix)),
                    ),
                }
            }
            others => (false, others),
        };
        let new_term = Spanned::new(new_term, term.span);
        if new {
            self.fold_term_as_type(new_term)
        } else {
            Ok(new_term)
        }
    }
/// Perform term folding expecting to yield a type.
///
/// This is a pre-processing step on terms. It is applied as soon as it is
/// clear that a certain term should yield a type, e.g. when mapping to a
/// subtype indication. This function performs certain precedence swaps and
/// combines terms into higher level ones, e.g. `Term::SubtypeInd`.
Perform term folding expecting to yield a type.
This is a pre-processing step on terms. It is applied as soon as it is
clear that a certain term should yield a type, e.g. when mapping to a
subtype indication. This function performs certain precedence swaps and
combines terms into higher level ones, e.g.
Perform term folding expecting to yield a type . This is a pre - processing step on terms . It is applied as soon as it is clear that a certain term should yield a type e . g . when mapping to a subtype indication . This function performs certain precedence swaps and combines terms into higher level ones e . g .
pub fn fold_term_as_type<'t>(&self, term: Spanned<Term<'t>>) -> Result<Spanned<Term<'t>>> {
        let (new, new_term) = match term.value {
            Term::Unresolved(name) => {
                self.emit(DiagBuilder2::error(format!("`{}` is unknown", name)).span(term.span));
                return Err(());
            }
            Term::RangeSuffix(subterm, range) => {
                let subterm = self.fold_term_as_type(*subterm)?;
                let range = self.fold_term_as_type(*range)?;
                match subterm.value {
                    // Fold `TypeMark range T` to `SubtypeInd`.
                    Term::TypeMark(tm) => (true, Term::SubtypeInd(tm, None, Some(Box::new(range)))),
                    // Fold `SubtypeInd range T` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, Some(con)) => {
                        let sp = Span::union(con.span, range.span);
                        let new_con = Spanned::new(Term::RangeSuffix(con, Box::new(range)), sp);
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(new_con))))
                    }
                    _ => (false, Term::RangeSuffix(Box::new(subterm), Box::new(range))),
                }
            }
            Term::SuffixParen(subterm, suffix) => {
                let subterm = self.fold_term_as_type(*subterm)?;
                let suffix = self.fold_term_as_type(*suffix)?;
                match subterm.value {
                    // Fold `TypeMark (T)` to `SubtypeInd`.
                    Term::TypeMark(tm) => {
                        (true, Term::SubtypeInd(tm, None, Some(Box::new(suffix))))
                    }
                    // Fold `SubtypeInd (T)` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, Some(con)) => {
                        let sp = Span::union(con.span, suffix.span);
                        let new_con = Spanned::new(Term::SuffixParen(con, Box::new(suffix)), sp);
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(new_con))))
                    }
                    // Fold `SubtypeInd (T)` to `SubtypeInd`.
                    Term::SubtypeInd(tm, resol, None) => {
                        (true, Term::SubtypeInd(tm, resol, Some(Box::new(suffix))))
                    }
                    _ => (
                        false,
                        Term::SuffixParen(Box::new(subterm), Box::new(suffix)),
                    ),
                }
            }
            others => (false, others),
        };
        let new_term = Spanned::new(new_term, term.span);
        if new {
            self.fold_term_as_type(new_term)
        } else {
            Ok(new_term)
        }
    }
pub fn fold_term_as_type < ' t > ( & self , term : Spanned < Term < ' t > > ) -> Result < Spanned < Term < ' t > > > { let ( new , new_term ) = match term . value { Term :: Unresolved ( name ) => { self . emit ( DiagBuilder2 :: error ( format ! ( " " name ) ) . span ( term . span ) ) ; return Err ( ( ) ) ; } Term :: RangeSuffix ( subterm , range ) => { let subterm = self . fold_term_as_type ( * subterm ) ? ; let range = self . fold_term_as_type ( * range ) ? ; match subterm . value { // Fold `TypeMark range T` to `SubtypeInd`. Term :: TypeMark ( tm ) => ( true , Term :: SubtypeInd ( tm , None , Some ( Box :: new ( range ) ) ) ) , // Fold `SubtypeInd range T` to `SubtypeInd`. Term :: SubtypeInd ( tm , resol , Some ( con ) ) => { let sp = Span :: union ( con . span , range . span ) ; let new_con = Spanned :: new ( Term :: RangeSuffix ( con , Box :: new ( range ) ) , sp ) ; ( true , Term :: SubtypeInd ( tm , resol , Some ( Box :: new ( new_con ) ) ) ) } _ => ( false , Term :: RangeSuffix ( Box :: new ( subterm ) , Box :: new ( range ) ) ) , } } Term :: SuffixParen ( subterm , suffix ) => { let subterm = self . fold_term_as_type ( * subterm ) ? ; let suffix = self . fold_term_as_type ( * suffix ) ? ; match subterm . value { // Fold `TypeMark (T)` to `SubtypeInd`. Term :: TypeMark ( tm ) => { ( true , Term :: SubtypeInd ( tm , None , Some ( Box :: new ( suffix ) ) ) ) } // Fold `SubtypeInd (T)` to `SubtypeInd`. Term :: SubtypeInd ( tm , resol , Some ( con ) ) => { let sp = Span :: union ( con . span , suffix . span ) ; let new_con = Spanned :: new ( Term :: SuffixParen ( con , Box :: new ( suffix ) ) , sp ) ; ( true , Term :: SubtypeInd ( tm , resol , Some ( Box :: new ( new_con ) ) ) ) } // Fold `SubtypeInd (T)` to `SubtypeInd`. Term :: SubtypeInd ( tm , resol , None ) => { ( true , Term :: SubtypeInd ( tm , resol , Some ( Box :: new ( suffix ) ) ) ) } _ => ( false , Term :: SuffixParen ( Box :: new ( subterm ) , Box :: new ( suffix ) ) , ) , } } others => ( false , others ) , } ; let new_term = Spanned :: new ( new_term , term . span ) ; if new { self . fold_term_as_type ( new_term ) } else { Ok ( new_term ) } }
Perform term folding expecting to yield a type.
Perform term folding expecting to yield a type .
&self
term
Spanned<Term<'t>>
&self
term
Spanned<Term<'t>>