summaryrefslogtreecommitdiff
path: root/dhall/src/semantics/resolve/resolve.rs
diff options
context:
space:
mode:
authorNadrieril2020-11-01 16:10:00 +0000
committerNadrieril2020-11-01 17:36:49 +0000
commit66ea301fc25a07485286560c434a9fdaf460c431 (patch)
treea0bc78be155be39e3da0ad5f61d7255057f8747a /dhall/src/semantics/resolve/resolve.rs
parent2c245e7f5ce4019381e0fa47a1e2caf6276106be (diff)
Untangle caching code
Diffstat (limited to 'dhall/src/semantics/resolve/resolve.rs')
-rw-r--r--dhall/src/semantics/resolve/resolve.rs86
1 files changed, 44 insertions, 42 deletions
diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs
index 8f8a9fe..d6bc4cd 100644
--- a/dhall/src/semantics/resolve/resolve.rs
+++ b/dhall/src/semantics/resolve/resolve.rs
@@ -220,6 +220,32 @@ fn make_aslocation_uniontype() -> Expr {
mkexpr(ExprKind::UnionType(union))
}
+fn check_hash(
+ import: &Import,
+ typed: &TypedHir,
+ span: Span,
+) -> Result<(), Error> {
+ match (import.mode, &import.hash) {
+ (ImportMode::Code, Some(Hash::SHA256(hash))) => {
+ let actual_hash = typed.0.to_expr_alpha().sha256_hash()?;
+ if hash[..] != actual_hash[..] {
+ mkerr(
+ ErrorBuilder::new("hash mismatch")
+ .span_err(span, "hash mismatch")
+ .note(format!("Expected sha256:{}", hex::encode(hash)))
+ .note(format!(
+ "Found sha256:{}",
+ hex::encode(actual_hash)
+ ))
+ .format(),
+ )?
+ }
+ }
+ _ => {}
+ }
+ Ok(())
+}
+
fn resolve_one_import(
env: &mut ImportEnv,
import: &Import,
@@ -228,44 +254,15 @@ fn resolve_one_import(
) -> Result<TypedHir, Error> {
match import.mode {
ImportMode::Code => {
- let (hir, ty) = env.file_cache.clone().caching_import(
- import,
- || location.fetch_dhall(),
- |parsed| {
- let typed = resolve_with_env(env, parsed)?.typecheck()?;
- let hir = typed.normalize().to_hir();
- Ok((hir, typed.ty))
- },
- )?;
- match &import.hash {
- Some(Hash::SHA256(hash)) => {
- let actual_hash = hir.to_expr_alpha().hash()?;
- if hash[..] != actual_hash[..] {
- mkerr(
- ErrorBuilder::new("hash mismatch")
- .span_err(span, "hash mismatch")
- .note(format!(
- "Expected sha256:{}",
- hex::encode(hash)
- ))
- .note(format!(
- "Found sha256:{}",
- hex::encode(actual_hash)
- ))
- .format(),
- )?
- }
- }
- None => {}
- }
- Ok((hir, ty))
+ let parsed = location.fetch_dhall()?;
+ let typed = resolve_with_env(env, parsed)?.typecheck()?;
+ let hir = typed.normalize().to_hir();
+ Ok((hir, typed.ty))
}
ImportMode::RawText => {
let text = location.fetch_text()?;
- let hir = Hir::new(
- HirKind::Expr(ExprKind::TextLit(text.into())),
- Span::Artificial,
- );
+ let hir =
+ Hir::new(HirKind::Expr(ExprKind::TextLit(text.into())), span);
Ok((hir, Type::from_builtin(Builtin::Text)))
}
ImportMode::Location => {
@@ -399,15 +396,20 @@ fn resolve_with_env(
let do_sanity_check = import.mode != ImportMode::Location;
let location =
base_location.chain(&import.location, do_sanity_check)?;
- if let Some(expr) = env.get_from_cache(&location) {
- return Ok(expr.clone());
+ // If the import is in the in-memory cache, or the hash is in the on-disk cache, return
+ // the cached contents.
+ if let Some(resolved) =
+ env.get_from_cache(&location, import.hash.as_ref())
+ {
+ return Ok(resolved);
}
- let expr = env.with_cycle_detection(location.clone(), |env| {
- resolve_one_import(env, &import, location.clone(), span)
+ let typed = env.with_cycle_detection(location.clone(), |env| {
+ resolve_one_import(env, &import, location.clone(), span.clone())
})?;
- // Add the resolved import to the cache
- env.set_cache(location, expr.clone());
- Ok(expr)
+ check_hash(&import, &typed, span)?;
+ // Add the resolved import to the caches
+ env.set_cache(location, import.hash.as_ref(), typed.clone());
+ Ok(typed)
},
)?;
Ok(Resolved(resolved))