From 7b4a4a870c4bbeffa4625a54fb82947b303054c7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 22 Mar 2016 04:22:42 -0400 Subject: [PATCH] Synthesize default action of `()` if type is `()` --- lalrpop/src/grammar/repr.rs | 7 +++++++ lalrpop/src/normalize/lower/mod.rs | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lalrpop/src/grammar/repr.rs b/lalrpop/src/grammar/repr.rs index dbcef9f..de7d01c 100644 --- a/lalrpop/src/grammar/repr.rs +++ b/lalrpop/src/grammar/repr.rs @@ -164,6 +164,13 @@ pub enum TypeRepr { } impl TypeRepr { + pub fn is_unit(&self) -> bool { + match *self { + TypeRepr::Tuple(ref v) => v.is_empty(), + _ => false, + } + } + pub fn usize() -> TypeRepr { TypeRepr::Nominal(NominalTypeRepr { path: Path::usize(), diff --git a/lalrpop/src/normalize/lower/mod.rs b/lalrpop/src/normalize/lower/mod.rs index d828b1e..8782130 100644 --- a/lalrpop/src/normalize/lower/mod.rs +++ b/lalrpop/src/normalize/lower/mod.rs @@ -257,7 +257,17 @@ impl LowerState { { let action = match action { Some(s) => s, - None => format!("(<>)"), + None => { + // If the user declared a type `()`, or we inferred + // it, then there is only one possible action that + // will type-check (`()`), so supply that. Otherwise, + // default is to include all selected items. + if nt_type.is_unit() { + format!("()") + } else { + format!("(<>)") + } + } }; // Note that the action fn takes ALL of the symbols in `expr`