diff options
author | Nadrieril | 2020-12-07 14:15:43 +0000 |
---|---|---|
committer | Nadrieril | 2020-12-07 19:34:39 +0000 |
commit | 8c5b3ff15f2125e9d731fc199e194e1993c36b37 (patch) | |
tree | a88ac770aa3e7605feed8381877f290a2b64cd43 /dhall/src/semantics/resolve | |
parent | 3c522217b7445c6df9e170d830f485086ad7e062 (diff) |
Thread cx everywhere else imports are read
Diffstat (limited to 'dhall/src/semantics/resolve')
-rw-r--r-- | dhall/src/semantics/resolve/cache.rs | 11 | ||||
-rw-r--r-- | dhall/src/semantics/resolve/env.rs | 18 | ||||
-rw-r--r-- | dhall/src/semantics/resolve/hir.rs | 20 | ||||
-rw-r--r-- | dhall/src/semantics/resolve/resolve.rs | 36 |
4 files changed, 51 insertions, 34 deletions
diff --git a/dhall/src/semantics/resolve/cache.rs b/dhall/src/semantics/resolve/cache.rs index 59463dd..9a5e835 100644 --- a/dhall/src/semantics/resolve/cache.rs +++ b/dhall/src/semantics/resolve/cache.rs @@ -68,11 +68,12 @@ impl Cache { pub fn insert<'cx>( &self, + cx: Ctxt<'cx>, hash: &Hash, expr: &Typed<'cx>, ) -> Result<(), Error> { let path = self.entry_path(hash); - write_cache_file(&path, expr) + write_cache_file(cx, &path, expr) } } @@ -97,8 +98,12 @@ fn read_cache_file<'cx>( } /// Write a file to the cache. -fn write_cache_file(path: &Path, expr: &Typed) -> Result<(), Error> { - let data = binary::encode(&expr.to_expr())?; +fn write_cache_file<'cx>( + cx: Ctxt<'cx>, + path: &Path, + expr: &Typed<'cx>, +) -> Result<(), Error> { + let data = binary::encode(&expr.to_expr(cx))?; File::create(path)?.write_all(data.as_slice())?; Ok(()) } diff --git a/dhall/src/semantics/resolve/env.rs b/dhall/src/semantics/resolve/env.rs index ba6205f..0d1952b 100644 --- a/dhall/src/semantics/resolve/env.rs +++ b/dhall/src/semantics/resolve/env.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; use crate::error::{Error, ImportError}; -use crate::semantics::{AlphaVar, Cache, ImportLocation, VarEnv}; +use crate::semantics::{check_hash, AlphaVar, Cache, ImportLocation, VarEnv}; use crate::syntax::{Hash, Label, V}; -use crate::{Ctxt, ImportResultId, Typed}; +use crate::{Ctxt, ImportId, ImportResultId, Typed}; /// Environment for resolving names. #[derive(Debug, Clone, Default)] @@ -95,6 +95,11 @@ impl<'cx> ImportEnv<'cx> { Some(expr) } + /// Invariant: the import must have been fetched. + pub fn check_hash(&self, import: ImportId<'cx>) -> Result<(), Error> { + check_hash(self.cx(), import) + } + pub fn write_to_mem_cache( &mut self, location: ImportLocation, @@ -103,10 +108,13 @@ impl<'cx> ImportEnv<'cx> { self.mem_cache.insert(location, result); } - pub fn write_to_disk_cache(&self, hash: &Option<Hash>, expr: &Typed<'cx>) { + /// Invariant: the import must have been fetched. + pub fn write_to_disk_cache(&self, import: ImportId<'cx>) { + let import = &self.cx()[import]; if let Some(disk_cache) = self.disk_cache.as_ref() { - if let Some(hash) = hash { - let _ = disk_cache.insert(hash, &expr); + if let Some(hash) = &import.import.hash { + let expr = import.unwrap_result(); + let _ = disk_cache.insert(self.cx(), hash, expr); } } } diff --git a/dhall/src/semantics/resolve/hir.rs b/dhall/src/semantics/resolve/hir.rs index c67ab75..5575888 100644 --- a/dhall/src/semantics/resolve/hir.rs +++ b/dhall/src/semantics/resolve/hir.rs @@ -51,22 +51,23 @@ impl<'cx> Hir<'cx> { } /// Converts a closed Hir expr back to the corresponding AST expression. - pub fn to_expr(&self, opts: ToExprOptions) -> Expr { - hir_to_expr(self, opts, &mut NameEnv::new()) + pub fn to_expr(&self, cx: Ctxt<'cx>, opts: ToExprOptions) -> Expr { + hir_to_expr(cx, self, opts, &mut NameEnv::new()) } /// Converts a closed Hir expr back to the corresponding AST expression. - pub fn to_expr_noopts(&self) -> Expr { + pub fn to_expr_noopts(&self, cx: Ctxt<'cx>) -> Expr { let opts = ToExprOptions { alpha: false }; - self.to_expr(opts) + self.to_expr(cx, opts) } - pub fn to_expr_alpha(&self) -> Expr { + pub fn to_expr_alpha(&self, cx: Ctxt<'cx>) -> Expr { let opts = ToExprOptions { alpha: true }; - self.to_expr(opts) + self.to_expr(cx, opts) } pub fn to_expr_tyenv(&self, env: &TyEnv<'cx>) -> Expr { let opts = ToExprOptions { alpha: false }; + let cx = env.cx(); let mut env = env.as_nameenv().clone(); - hir_to_expr(self, opts, &mut env) + hir_to_expr(cx, self, opts, &mut env) } /// Typecheck the Hir. @@ -95,6 +96,7 @@ impl<'cx> Hir<'cx> { } fn hir_to_expr<'cx>( + cx: Ctxt<'cx>, hir: &Hir<'cx>, opts: ToExprOptions, env: &mut NameEnv, @@ -103,14 +105,14 @@ fn hir_to_expr<'cx>( HirKind::Var(v) if opts.alpha => ExprKind::Var(V("_".into(), v.idx())), HirKind::Var(v) => ExprKind::Var(env.label_var(*v)), HirKind::Import(hir, _) => { - return hir_to_expr(hir, opts, &mut NameEnv::new()) + return hir_to_expr(cx, hir, opts, &mut NameEnv::new()); } HirKind::Expr(e) => { let e = e.map_ref_maybe_binder(|l, hir| { if let Some(l) = l { env.insert_mut(l); } - let e = hir_to_expr(hir, opts, env); + let e = hir_to_expr(cx, hir, opts, env); if l.is_some() { env.remove_mut(); } diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs index 9021155..db162ef 100644 --- a/dhall/src/semantics/resolve/resolve.rs +++ b/dhall/src/semantics/resolve/resolve.rs @@ -287,19 +287,21 @@ fn make_aslocation_uniontype() -> Expr { mkexpr(ExprKind::UnionType(union)) } -fn check_hash<'cx>( - import: &Import, - typed: &Typed<'cx>, - span: Span, +/// Invariant: the import must have been fetched. +pub fn check_hash<'cx>( + cx: Ctxt<'cx>, + import: ImportId<'cx>, ) -> Result<(), Error> { + let import = &cx[import]; if let (ImportMode::Code, Some(Hash::SHA256(hash))) = - (import.mode, &import.hash) + (import.import.mode, &import.import.hash) { - let actual_hash = typed.hir.to_expr_alpha().sha256_hash()?; + let expr = import.unwrap_result().hir.to_expr_alpha(cx); + let actual_hash = expr.sha256_hash()?; if hash[..] != actual_hash[..] { mkerr( ErrorBuilder::new("hash mismatch") - .span_err(span, "hash mismatch") + .span_err(import.span.clone(), "hash mismatch") .note(format!("Expected sha256:{}", hex::encode(hash))) .note(format!( "Found sha256:{}", @@ -411,15 +413,14 @@ fn fetch_import<'cx>( cx[import_id].set_resultid(res_id); // The same location may be used with different or no hashes. Thus we need to check // the hashes every time. - let typed = &cx[res_id]; - check_hash(import, typed, span)?; - env.write_to_disk_cache(&import.hash, typed); + env.check_hash(import_id)?; + env.write_to_disk_cache(import_id); return Ok(()); } if let Some(typed) = env.get_from_disk_cache(&import.hash) { - // No need to check the hash, it was checked before reading the file. We also don't - // write to the in-memory cache, because the location might be completely unrelated - // to the cached file (e.g. `missing sha256:...` is valid). + // No need to check the hash, it was checked before reading the file. + // We also don't write to the in-memory cache, because the location might be completely + // unrelated to the cached file (e.g. `missing sha256:...` is valid). // This actually means that importing many times a same hashed import will take // longer than importing many times a same non-hashed import. cx[import_id].set_result(typed); @@ -441,9 +442,10 @@ fn fetch_import<'cx>( }; // Add the resolved import to the caches - check_hash(import, &typed, span)?; - env.write_to_disk_cache(&import.hash, &typed); - let res_id = cx[import_id].set_result(typed); + let res_id = cx[import_id].set_result(typed.clone()); + env.check_hash(import_id)?; + env.write_to_disk_cache(import_id); + // Cache the mapping from this location to the result. env.write_to_mem_cache(location, res_id); Ok(()) @@ -462,7 +464,7 @@ fn resolve_with_env<'cx>( env.cx().push_import(base_location.clone(), import, span); fetch_import(env, import_id)?; // TODO: store import id in Hir - Ok(env.cx()[import_id].get_result().unwrap().clone()) + Ok(env.cx()[import_id].unwrap_result().clone()) }, )?; Ok(Resolved(resolved)) |