From 00e7ca206f7051c3f41173e5e6193cedbc09fe90 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 5 Nov 2021 14:05:38 -0700 Subject: [PATCH] ISLE: add a missing type check for whether terms used in expressions have a constructor --- cranelift/isle/isle/src/ast.rs | 19 +++++++++++++++++++ cranelift/isle/isle/src/sema.rs | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/cranelift/isle/isle/src/ast.rs b/cranelift/isle/isle/src/ast.rs index 4b2aa84ca0..57f257a892 100644 --- a/cranelift/isle/isle/src/ast.rs +++ b/cranelift/isle/isle/src/ast.rs @@ -338,6 +338,25 @@ impl Expr { | &Expr::Let { pos, .. } => pos, } } + + /// Call `f` for each of the terms in this expression. + pub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident)) { + match self { + Expr::Term { sym, args, pos } => { + f(*pos, sym); + for arg in args { + arg.terms(f); + } + } + Expr::Let { defs, body, .. } => { + for def in defs { + def.val.terms(f); + } + body.terms(f); + } + Expr::Var { .. } | Expr::ConstInt { .. } | Expr::ConstPrim { .. } => {} + } + } } /// One variable locally bound in a `(let ...)` expression. diff --git a/cranelift/isle/isle/src/sema.rs b/cranelift/isle/isle/src/sema.rs index 0aae69a2b9..40210709fc 100644 --- a/cranelift/isle/isle/src/sema.rs +++ b/cranelift/isle/isle/src/sema.rs @@ -767,6 +767,7 @@ impl TermEnv { tyenv.return_errors()?; env.collect_rules(tyenv, defs); env.check_for_undefined_decls(tyenv, defs); + env.check_for_expr_terms_without_constructors(tyenv, defs); tyenv.return_errors()?; Ok(env) @@ -1283,6 +1284,28 @@ impl TermEnv { } } + fn check_for_expr_terms_without_constructors(&self, tyenv: &mut TypeEnv, defs: &ast::Defs) { + for def in &defs.defs { + if let ast::Def::Rule(rule) = def { + rule.expr.terms(&mut |pos, ident| { + let sym = tyenv.intern_mut(ident); + let term = self.term_map[&sym]; + let term = &self.terms[term.index()]; + if !term.has_constructor() { + tyenv.report_error( + pos, + format!( + "term `{}` cannot be used in an expression because \ + it does not have a constructor", + ident.0 + ), + ) + } + }); + } + } + } + fn translate_pattern( &self, tyenv: &mut TypeEnv,