Skip to content

cannot infer an appropriate lifetime #3

@brendanzab

Description

@brendanzab

I'm experimenting with making a type checker using eff. Eventually I want to try implementing "An Algebraic Approach to Typechecking and Elaboration" using it.

use eff::{eff, Effect};

#[derive(Debug)]
pub struct Report(pub String);

impl Effect for Report {
    type Output = ();
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Type {
    Base,
    Fun(Box<Type>, Box<Type>),
    Error,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Term {
    Var(usize),
    FunIntro(Box<Type>, Box<Term>),
    FunElim(Box<Term>, Box<Term>),
}

#[eff(Report)]
pub fn ty_check(context: &mut Vec<Type>, term: &Term) -> Type {
    match term {
        Term::Var(index) => match context.get(*index) {
            Some(ty) => ty.clone(),
            None => {
                eff::perform!(Report("unknown variable".to_owned()));
                Type::Error
            }
        },
        Term::FunIntro(ty, body) => {
            context.push((**ty).clone());
            let body_ty = eff::perform_from!(ty_check(context, body));
            context.pop();
            body_ty
        }
        Term::FunElim(fun, arg) => match eff::perform_from!(ty_check(context, fun)) {
            Type::Fun(param_ty, body_ty) => match eff::perform_from!(ty_check(context, arg)) {
                Type::Error => Type::Error,
                arg_ty if arg_ty == *param_ty => (*body_ty).clone(),
                _ => {
                    eff::perform!(Report("mismatched parameter".to_owned()));
                    Type::Error
                }
            },
            _ => Type::Error,
        },
    }
}

Sadly I get the following error:

error: cannot infer an appropriate lifetime
  --> src/lam1_eff.rs:24:1
   |
24 | #[eff(Report)]
   | ^^^^^^^^^^^^^^
   | |
   | this return type evaluates to the `'static` lifetime...
   | ...but this borrow...
   |
note: ...can't outlive the anonymous lifetime #2 defined on the function body at 24:14
  --> src/lam1_eff.rs:24:14
   |
24 | #[eff(Report)]
   |              ^
help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #2 defined on the function body at 24:14
   |
24 | #[eff(Report)] + '_
   |

error: cannot infer an appropriate lifetime
  --> src/lam1_eff.rs:24:1
   |
24 | #[eff(Report)]
   | ^^^^^^^^^^^^^^
   | |
   | this return type evaluates to the `'static` lifetime...
   | ...but this borrow...
   |
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 24:14
  --> src/lam1_eff.rs:24:14
   |
24 | #[eff(Report)]
   |              ^
help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 24:14
   |
24 | #[eff(Report)] + '_
   |

error: aborting due to 2 previous errors

Any thoughts on what might be causing this?

In addition, it was a bit of a challenge to figure out how to call an effectful function recusively, seeing as there's no example of this! I had to find it in the state test! Might be handy to make it more prominent in the docs if you have a chance! :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions