summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2020-03-04 21:36:41 +0000
committerNadrieril2020-03-05 15:58:54 +0000
commit31cefbdf0364a3d224420365049885051734669b (patch)
tree6d4c6a0186700961801f238b976ab9d8781c507e
parent903d6c0bba36a6696eb337ae84b962f4cc48b5b5 (diff)
Cache imports correctly
-rw-r--r--dhall/build.rs3
-rw-r--r--dhall/src/error/mod.rs4
-rw-r--r--dhall/src/semantics/resolve/env.rs24
-rw-r--r--dhall/src/semantics/resolve/resolve.rs14
-rw-r--r--dhall/tests/import/failure/cycle.txt2
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"))