summaryrefslogtreecommitdiff
path: root/dhall/src/semantics
diff options
context:
space:
mode:
authorNadrieril2020-03-04 21:36:41 +0000
committerNadrieril2020-03-05 15:58:54 +0000
commit31cefbdf0364a3d224420365049885051734669b (patch)
tree6d4c6a0186700961801f238b976ab9d8781c507e /dhall/src/semantics
parent903d6c0bba36a6696eb337ae84b962f4cc48b5b5 (diff)
Cache imports correctly
Diffstat (limited to 'dhall/src/semantics')
-rw-r--r--dhall/src/semantics/resolve/env.rs24
-rw-r--r--dhall/src/semantics/resolve/resolve.rs14
2 files changed, 19 insertions, 19 deletions
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))