From 7a392b07166c089979e69d4c8a68da3298964c28 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 7 Dec 2020 17:48:20 +0000 Subject: Defer name errors to typechecking We aren't supposed to inspect anything before alternatives are chosen --- dhall/src/semantics/resolve/hir.rs | 3 +++ dhall/src/semantics/resolve/resolve.rs | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'dhall/src/semantics/resolve') diff --git a/dhall/src/semantics/resolve/hir.rs b/dhall/src/semantics/resolve/hir.rs index 3e282b4..05a8550 100644 --- a/dhall/src/semantics/resolve/hir.rs +++ b/dhall/src/semantics/resolve/hir.rs @@ -13,6 +13,8 @@ pub struct AlphaVar { pub enum HirKind<'cx> { /// A resolved variable (i.e. a DeBruijn index) Var(AlphaVar), + /// A variable that couldn't be resolved. Detected during resolution, but causes an error during typeck. + MissingVar(V), /// An import. It must have been resolved by the time we get to typechecking/normalization. Import(ImportId<'cx>), // Forbidden ExprKind variants: Var, Import, Completion @@ -104,6 +106,7 @@ fn hir_to_expr<'cx>( let kind = match hir.kind() { HirKind::Var(v) if opts.alpha => ExprKind::Var(V("_".into(), v.idx())), HirKind::Var(v) => ExprKind::Var(env.label_var(*v)), + HirKind::MissingVar(v) => ExprKind::Var(v.clone()), HirKind::Import(import) => { let typed = cx[import].unwrap_result(); return hir_to_expr(cx, &typed.hir, opts, &mut NameEnv::new()); diff --git a/dhall/src/semantics/resolve/resolve.rs b/dhall/src/semantics/resolve/resolve.rs index 7450825..c4cd518 100644 --- a/dhall/src/semantics/resolve/resolve.rs +++ b/dhall/src/semantics/resolve/resolve.rs @@ -377,11 +377,7 @@ fn traverse_resolve_expr<'cx>( Ok(match expr.kind() { ExprKind::Var(var) => match name_env.unlabel_var(&var) { Some(v) => Hir::new(HirKind::Var(v), expr.span()), - None => mkerr( - ErrorBuilder::new(format!("unbound variable `{}`", var)) - .span_err(expr.span(), "not found in this scope") - .format(), - )?, + None => Hir::new(HirKind::MissingVar(var.clone()), expr.span()), }, ExprKind::Op(OpKind::BinOp(BinOp::ImportAlt, l, r)) => { match traverse_resolve_expr(name_env, l, f) { @@ -492,6 +488,8 @@ fn resolve_with_env<'cx>( Ok(Resolved(resolved)) } +/// Resolves all imports and names. Returns errors if importing failed. Name errors are deferred to +/// typechecking. pub fn resolve<'cx>( cx: Ctxt<'cx>, parsed: Parsed, @@ -499,6 +497,7 @@ pub fn resolve<'cx>( resolve_with_env(&mut ImportEnv::new(cx), parsed) } +/// Resolves names and errors if we find any imports. pub fn skip_resolve<'cx>( cx: Ctxt<'cx>, parsed: Parsed, -- cgit v1.2.3