diff options
author | Nadrieril | 2020-03-04 21:36:41 +0000 |
---|---|---|
committer | Nadrieril | 2020-03-05 15:58:54 +0000 |
commit | 31cefbdf0364a3d224420365049885051734669b (patch) | |
tree | 6d4c6a0186700961801f238b976ab9d8781c507e | |
parent | 903d6c0bba36a6696eb337ae84b962f4cc48b5b5 (diff) |
Cache imports correctly
Diffstat (limited to '')
-rw-r--r-- | dhall/build.rs | 3 | ||||
-rw-r--r-- | dhall/src/error/mod.rs | 4 | ||||
-rw-r--r-- | dhall/src/semantics/resolve/env.rs | 24 | ||||
-rw-r--r-- | dhall/src/semantics/resolve/resolve.rs | 14 | ||||
-rw-r--r-- | dhall/tests/import/failure/cycle.txt | 2 |
5 files changed, 22 insertions, 25 deletions
diff --git a/dhall/build.rs b/dhall/build.rs index 565c37e..4bd56a3 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -324,9 +324,6 @@ fn generate_tests() -> std::io::Result<()> { // Too slow, but also not all features implemented // For now needs support for hashed imports || path == "prelude" - // TODO: remote imports - || path == "CacheImports" - || path == "CacheImportsCanonicalize" }), input_type: FileType::Text, output_type: Some(FileType::Text), diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs index 29dd5ad..6dd8393 100644 --- a/dhall/src/error/mod.rs +++ b/dhall/src/error/mod.rs @@ -1,6 +1,6 @@ use std::io::Error as IOError; -use crate::semantics::resolve::ImportStack; +use crate::semantics::resolve::{ImportLocation, ImportStack}; use crate::syntax::{Import, ParseError}; mod builder; @@ -29,7 +29,7 @@ pub(crate) enum ImportError { Missing, MissingEnvVar, UnexpectedImport(Import<()>), - ImportCycle(ImportStack, Import<()>), + ImportCycle(ImportStack, ImportLocation), Url(url::ParseError), } diff --git a/dhall/src/semantics/resolve/env.rs b/dhall/src/semantics/resolve/env.rs index 43676cc..2342dcc 100644 --- a/dhall/src/semantics/resolve/env.rs +++ b/dhall/src/semantics/resolve/env.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::error::{Error, ImportError}; -use crate::semantics::{AlphaVar, Import, TypedHir, VarEnv}; +use crate::semantics::{AlphaVar, ImportLocation, TypedHir, VarEnv}; use crate::syntax::{Label, V}; /// Environment for resolving names. @@ -10,8 +10,8 @@ pub(crate) struct NameEnv { names: Vec<Label>, } -pub(crate) type ImportCache = HashMap<Import, TypedHir>; -pub(crate) type ImportStack = Vec<Import>; +pub(crate) type ImportCache = HashMap<ImportLocation, TypedHir>; +pub(crate) type ImportStack = Vec<ImportLocation>; /// Environment for resolving imports #[derive(Debug, Clone)] @@ -74,28 +74,28 @@ impl ImportEnv { pub fn handle_import( &mut self, - import: Import, - mut do_resolve: impl FnMut(&mut Self, &Import) -> Result<TypedHir, Error>, + location: ImportLocation, + do_resolve: impl FnOnce(&mut Self) -> Result<TypedHir, Error>, ) -> Result<TypedHir, Error> { - if self.stack.contains(&import) { + if self.stack.contains(&location) { return Err( - ImportError::ImportCycle(self.stack.clone(), import).into() + ImportError::ImportCycle(self.stack.clone(), location).into() ); } - Ok(match self.cache.get(&import) { + Ok(match self.cache.get(&location) { Some(expr) => expr.clone(), None => { // Push the current import on the stack - self.stack.push(import.clone()); + self.stack.push(location); // Resolve the import recursively - let expr = do_resolve(self, &import)?; + let expr = do_resolve(self)?; // Remove import from the stack. - self.stack.pop(); + let location = self.stack.pop().unwrap(); // Add the import to the cache - self.cache.insert(import, expr.clone()); + self.cache.insert(location, expr.clone()); expr } diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs index 782f5f7..d8115f8 100644 --- a/dhall/src/semantics/resolve/resolve.rs +++ b/dhall/src/semantics/resolve/resolve.rs @@ -22,7 +22,7 @@ pub(crate) type Import = syntax::Import<()>; pub(crate) type TypedHir = (Hir, Type); /// The location of some data, usually some dhall code. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) enum ImportLocation { /// Local file Local(PathBuf), @@ -143,9 +143,8 @@ fn make_aslocation_uniontype() -> Expr { fn resolve_one_import( env: &mut ImportEnv, import: &Import, - location: &ImportLocation, + location: ImportLocation, ) -> Result<TypedHir, Error> { - let location = location.chain(&import.location)?; match import.mode { ImportMode::Code => { let parsed = match location { @@ -189,7 +188,7 @@ fn resolve_one_import( ("Local", Some(path.to_string_lossy().into_owned())) } ImportLocation::Remote(url) => { - ("Remote", Some(url.to_string())) + ("Remote", Some(url.into_string())) } ImportLocation::Env(name) => ("Environment", Some(name)), ImportLocation::Missing => ("Missing", None), @@ -299,11 +298,12 @@ fn resolve_with_env( env: &mut ImportEnv, parsed: Parsed, ) -> Result<Resolved, Error> { - let Parsed(expr, root) = parsed; + let Parsed(expr, location) = parsed; let resolved = traverse_resolve_expr(&mut NameEnv::new(), &expr, &mut |import| { - env.handle_import(import, |env, import| { - resolve_one_import(env, import, &root) + let location = location.chain(&import.location)?; + env.handle_import(location.clone(), |env| { + resolve_one_import(env, &import, location) }) })?; Ok(Resolved(resolved)) diff --git a/dhall/tests/import/failure/cycle.txt b/dhall/tests/import/failure/cycle.txt index 4e9488e..f5a1abf 100644 --- a/dhall/tests/import/failure/cycle.txt +++ b/dhall/tests/import/failure/cycle.txt @@ -1 +1 @@ -ImportCycle([Import { mode: Code, location: Local(Parent, FilePath { file_path: ["data", "cycle.dhall"] }), hash: None }, Import { mode: Code, location: Local(Parent, FilePath { file_path: ["failure", "cycle.dhall"] }), hash: None }], Import { mode: Code, location: Local(Parent, FilePath { file_path: ["data", "cycle.dhall"] }), hash: None }) +ImportCycle([Local("./dhall-lang/tests/import/data/cycle.dhall"), Local("./dhall-lang/tests/import/failure/cycle.dhall")], Local("./dhall-lang/tests/import/data/cycle.dhall")) |