diff options
author | Nadrieril | 2019-04-11 16:41:06 +0200 |
---|---|---|
committer | Nadrieril | 2019-04-11 19:21:03 +0200 |
commit | d17d553a39aa3bffdfc19b7fe4801b85d6bd80f7 (patch) | |
tree | b04c707f865b98889414022f8aa639b1f541f671 | |
parent | 7ba857a96eebbdd1cef0aa22407c870887d24aed (diff) |
Add lifetime parameters to Parsed and Resolved
Future-proofing
-rw-r--r-- | dhall/src/expr.rs | 35 | ||||
-rw-r--r-- | dhall/src/imports.rs | 27 | ||||
-rw-r--r-- | dhall/src/tests.rs | 3 | ||||
-rw-r--r-- | dhall/src/traits/deserialize.rs | 8 | ||||
-rw-r--r-- | dhall/src/typecheck.rs | 2 |
5 files changed, 52 insertions, 23 deletions
diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 1ce20e3..e3a2fe5 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -1,5 +1,6 @@ use crate::imports::ImportRoot; use dhall_core::*; +use std::marker::PhantomData; macro_rules! derive_other_traits { ($ty:ident) => { @@ -20,13 +21,39 @@ macro_rules! derive_other_traits { }; } +macro_rules! derive_other_traits_ { + ($ty:ident) => { + impl<'a> std::cmp::PartialEq for $ty<'a> { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl<'a> std::fmt::Display for $ty<'a> { + fn fmt( + &self, + f: &mut std::fmt::Formatter, + ) -> Result<(), std::fmt::Error> { + self.0.fmt(f) + } + } + }; +} + #[derive(Debug, Clone, Eq)] -pub struct Parsed(pub(crate) SubExpr<X, Import>, pub(crate) ImportRoot); -derive_other_traits!(Parsed); +pub struct Parsed<'a>( + pub(crate) SubExpr<X, Import>, + pub(crate) ImportRoot, + pub(crate) PhantomData<&'a ()>, +); +derive_other_traits_!(Parsed); #[derive(Debug, Clone, Eq)] -pub struct Resolved(pub(crate) SubExpr<X, Normalized>); -derive_other_traits!(Resolved); +pub struct Resolved<'a>( + pub(crate) SubExpr<X, Normalized>, + pub(crate) PhantomData<&'a ()>, +); +derive_other_traits_!(Resolved); #[derive(Debug, Clone, Eq)] pub struct Typed(pub(crate) SubExpr<X, Normalized>, pub(crate) Option<Type>); diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index b5546b2..6b6e2e7 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -3,6 +3,7 @@ use crate::expr::*; use dhall_core::*; use std::fs::File; use std::io::Read; +use std::marker::PhantomData; use std::path::Path; use std::path::PathBuf; @@ -48,10 +49,10 @@ fn load_import(f: &Path) -> Result<Normalized, Error> { Ok(Parsed::parse_file(f)?.resolve()?.typecheck()?.normalize()) } -fn resolve_expr( - Parsed(expr, root): Parsed, +fn resolve_expr<'a>( + Parsed(expr, root, marker): Parsed<'a>, allow_imports: bool, -) -> Result<Resolved, ImportError> { +) -> Result<Resolved<'a>, ImportError> { let resolve = |import: &Import| -> Result<Normalized, ImportError> { if allow_imports { let expr = resolve_import(import, &root)?; @@ -61,36 +62,36 @@ fn resolve_expr( } }; let expr = expr.as_ref().traverse_embed(&resolve)?; - Ok(Resolved(rc(expr))) + Ok(Resolved(rc(expr), marker)) } -impl Parsed { - pub fn parse_file(f: &Path) -> Result<Parsed, Error> { +impl<'a> Parsed<'a> { + pub fn parse_file(f: &Path) -> Result<Parsed<'a>, Error> { let mut buffer = String::new(); File::open(f)?.read_to_string(&mut buffer)?; let expr = parse_expr(&*buffer)?; let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); - Ok(Parsed(expr, root)) + Ok(Parsed(expr, root, PhantomData)) } - pub fn parse_str(s: &str) -> Result<Parsed, Error> { + pub fn parse_str(s: &'a str) -> Result<Parsed<'a>, Error> { let expr = parse_expr(s)?; let root = ImportRoot::LocalDir(std::env::current_dir()?); - Ok(Parsed(expr, root)) + Ok(Parsed(expr, root, PhantomData)) } - pub fn parse_binary_file(f: &Path) -> Result<Parsed, Error> { + pub fn parse_binary_file(f: &Path) -> Result<Parsed<'a>, Error> { let mut buffer = Vec::new(); File::open(f)?.read_to_end(&mut buffer)?; let expr = crate::binary::decode(&buffer)?; let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); - Ok(Parsed(expr, root)) + Ok(Parsed(expr, root, PhantomData)) } - pub fn resolve(self) -> Result<Resolved, ImportError> { + pub fn resolve(self) -> Result<Resolved<'a>, ImportError> { crate::imports::resolve_expr(self, true) } - pub fn skip_resolve(self) -> Result<Resolved, ImportError> { + pub fn skip_resolve(self) -> Result<Resolved<'a>, ImportError> { crate::imports::resolve_expr(self, false) } } diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 798f3e9..14c2a5f 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -99,7 +99,8 @@ pub fn run_test( assert_eq_pretty!(expr, expected); // Round-trip pretty-printer - let expr: Parsed = crate::from_str(&expr.to_string(), None)?; + let expr_string = expr.to_string(); + let expr: Parsed = crate::from_str(&expr_string, None)?; assert_eq!(expr, expected); return Ok(()); diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs index 1fbdfe1..3e8cc5e 100644 --- a/dhall/src/traits/deserialize.rs +++ b/dhall/src/traits/deserialize.rs @@ -5,18 +5,18 @@ pub trait Deserialize<'a>: Sized { fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self>; } -impl<'a> Deserialize<'a> for Parsed { +impl<'de: 'a, 'a> Deserialize<'de> for Parsed<'a> { /// Simply parses the provided string. Ignores the /// provided type. - fn from_str(s: &'a str, _: Option<&Type>) -> Result<Self> { + fn from_str(s: &'de str, _: Option<&Type>) -> Result<Self> { Ok(Parsed::parse_str(s)?) } } -impl<'a> Deserialize<'a> for Resolved { +impl<'de: 'a, 'a> Deserialize<'de> for Resolved<'a> { /// Parses and resolves the provided string. Ignores the /// provided type. - fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> { + fn from_str(s: &'de str, ty: Option<&Type>) -> Result<Self> { Ok(Parsed::from_str(s, ty)?.resolve()?) } } diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index 4881972..41c1b69 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -11,7 +11,7 @@ use dhall_generator as dhall; use self::TypeMessage::*; -impl Resolved { +impl<'a> Resolved<'a> { pub fn typecheck(self) -> Result<Typed, TypeError> { type_of(self.0.clone()) } |