From 57fb440349443b20a6b72ee04f93e0abc4d03e56 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 12 Apr 2019 21:44:47 +0200 Subject: Restrict public API to its most minimal expression --- dhall/src/error.rs | 1 + dhall/src/expr.rs | 12 ++-- dhall/src/imports.rs | 3 + dhall/src/lib.rs | 8 +-- dhall/src/main.rs | 160 +++++++++++++++++++++++++------------------------ dhall/src/normalize.rs | 1 + dhall/src/tests.rs | 2 +- dhall/src/typecheck.rs | 25 ++++---- 8 files changed, 111 insertions(+), 101 deletions(-) diff --git a/dhall/src/error.rs b/dhall/src/error.rs index 1243c94..b987165 100644 --- a/dhall/src/error.rs +++ b/dhall/src/error.rs @@ -1,6 +1,7 @@ pub type Result = std::result::Result; #[derive(Debug)] +#[non_exhaustive] pub enum Error { IO(std::io::Error), Parse(dhall_core::ParseError), diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index ab59ce0..6f9f280 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -22,18 +22,20 @@ macro_rules! derive_other_traits { } #[derive(Debug, Clone, Eq)] -pub struct Parsed<'a>( +pub(crate) struct Parsed<'a>( pub(crate) SubExpr, Import>, pub(crate) ImportRoot, ); derive_other_traits!(Parsed); #[derive(Debug, Clone, Eq)] -pub struct Resolved<'a>(pub(crate) SubExpr, Normalized<'static>>); +pub(crate) struct Resolved<'a>( + pub(crate) SubExpr, Normalized<'static>>, +); derive_other_traits!(Resolved); #[derive(Debug, Clone, Eq)] -pub struct Typed<'a>( +pub(crate) struct Typed<'a>( pub(crate) SubExpr>, pub(crate) Option>, pub(crate) PhantomData<&'a ()>, @@ -41,7 +43,7 @@ pub struct Typed<'a>( derive_other_traits!(Typed); #[derive(Debug, Clone, Eq)] -pub struct Normalized<'a>( +pub(crate) struct Normalized<'a>( pub(crate) SubExpr, pub(crate) Option>, pub(crate) PhantomData<&'a ()>, @@ -90,6 +92,7 @@ impl<'a> From> for Typed<'a> { } } +#[doc(hidden)] impl<'a> Typed<'a> { pub(crate) fn as_expr(&self) -> &SubExpr> { &self.0 @@ -99,6 +102,7 @@ impl<'a> Typed<'a> { } } +#[doc(hidden)] impl<'a> Normalized<'a> { pub(crate) fn as_expr(&self) -> &SubExpr { &self.0 diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index 36f0802..ff28ab2 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -80,6 +80,7 @@ impl<'a> Parsed<'a> { Ok(Parsed(expr, root)) } + #[allow(dead_code)] pub fn parse_binary_file(f: &Path) -> Result, Error> { let mut buffer = Vec::new(); File::open(f)?.read_to_end(&mut buffer)?; @@ -91,6 +92,8 @@ impl<'a> Parsed<'a> { pub fn resolve(self) -> Result, ImportError> { crate::imports::resolve_expr(self, true) } + + #[allow(dead_code)] pub fn skip_resolve(self) -> Result, ImportError> { crate::imports::resolve_expr(self, false) } diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 6d08d08..73f3c1b 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -2,6 +2,7 @@ #![feature(proc_macro_hygiene)] #![feature(slice_patterns)] #![feature(label_break_value)] +#![feature(non_exhaustive)] #![cfg_attr(test, feature(custom_inner_attributes))] #![allow( clippy::type_complexity, @@ -126,13 +127,12 @@ mod imports; mod normalize; mod traits; mod typecheck; -pub use crate::traits::{ - Deserialize, DynamicType, SimpleStaticType, StaticType, -}; +pub use crate::traits::{Deserialize, SimpleStaticType, StaticType}; +#[doc(hidden)] pub use dhall_generator::SimpleStaticType; pub mod error; pub mod expr; -pub mod serde; +mod serde; pub fn from_str<'a, T: Deserialize<'a>>( s: &'a str, diff --git a/dhall/src/main.rs b/dhall/src/main.rs index 3b61a44..e25a535 100644 --- a/dhall/src/main.rs +++ b/dhall/src/main.rs @@ -1,91 +1,93 @@ -use std::error::Error; -use std::io::{self, Read}; -use term_painter::ToStyle; +// use std::error::Error; +// use std::io::{self, Read}; +// use term_painter::ToStyle; -const ERROR_STYLE: term_painter::Color = term_painter::Color::Red; -const BOLD: term_painter::Attr = term_painter::Attr::Bold; +// const ERROR_STYLE: term_painter::Color = term_painter::Color::Red; +// const BOLD: term_painter::Attr = term_painter::Attr::Bold; -fn print_error(message: &str, source: &str, start: usize, end: usize) { - let line_number = bytecount::count(source[..start].as_bytes(), b'\n'); - let line_start = source[..start].rfind('\n').map(|i| i + 1).unwrap_or(0); - let line_end = source[end..].find('\n').unwrap_or(0) + end; - let context_prefix = &source[line_start..start]; - let context_highlighted = &source[start..end]; - let context_suffix = &source[end..line_end]; +// fn print_error(message: &str, source: &str, start: usize, end: usize) { +// let line_number = bytecount::count(source[..start].as_bytes(), b'\n'); +// let line_start = source[..start].rfind('\n').map(|i| i + 1).unwrap_or(0); +// let line_end = source[end..].find('\n').unwrap_or(0) + end; +// let context_prefix = &source[line_start..start]; +// let context_highlighted = &source[start..end]; +// let context_suffix = &source[end..line_end]; - let line_number_str = line_number.to_string(); - let line_number_width = line_number_str.len(); +// let line_number_str = line_number.to_string(); +// let line_number_width = line_number_str.len(); - BOLD.with(|| { - ERROR_STYLE.with(|| { - print!("error: "); - }); - println!("{}", message); - }); - BOLD.with(|| { - print!(" -->"); - }); - println!(" (stdin):{}:0", line_number); - BOLD.with(|| { - println!("{:w$} |", "", w = line_number_width); - print!("{} |", line_number_str); - }); - print!(" {}", context_prefix); - BOLD.with(|| { - ERROR_STYLE.with(|| { - print!("{}", context_highlighted); - }); - }); - println!("{}", context_suffix); - BOLD.with(|| { - print!("{:w$} |", "", w = line_number_width); - ERROR_STYLE.with(|| { - println!( - " {:so$}{:^>ew$}", - "", - "", - so = source[line_start..start].chars().count(), - ew = ::std::cmp::max(1, source[start..end].chars().count()) - ); - }); - }); -} +// BOLD.with(|| { +// ERROR_STYLE.with(|| { +// print!("error: "); +// }); +// println!("{}", message); +// }); +// BOLD.with(|| { +// print!(" -->"); +// }); +// println!(" (stdin):{}:0", line_number); +// BOLD.with(|| { +// println!("{:w$} |", "", w = line_number_width); +// print!("{} |", line_number_str); +// }); +// print!(" {}", context_prefix); +// BOLD.with(|| { +// ERROR_STYLE.with(|| { +// print!("{}", context_highlighted); +// }); +// }); +// println!("{}", context_suffix); +// BOLD.with(|| { +// print!("{:w$} |", "", w = line_number_width); +// ERROR_STYLE.with(|| { +// println!( +// " {:so$}{:^>ew$}", +// "", +// "", +// so = source[line_start..start].chars().count(), +// ew = ::std::cmp::max(1, source[start..end].chars().count()) +// ); +// }); +// }); +// } fn main() { - let mut buffer = String::new(); - io::stdin().read_to_string(&mut buffer).unwrap(); + // let mut buffer = String::new(); + // io::stdin().read_to_string(&mut buffer).unwrap(); - let expr = match dhall::expr::Parsed::parse_str(&buffer) { - Ok(expr) => expr, - Err(e) => { - print_error(&format!("Parse error {}", e), &buffer, 0, 0); - return; - } - }; + // TODO: public API is too restricted for this + // let expr = match dhall::expr::Parsed::parse_str(&buffer) { + // Ok(expr) => expr, + // Err(e) => { + // print_error(&format!("Parse error {}", e), &buffer, 0, 0); + // return; + // } + // }; - let expr = expr.resolve().unwrap(); + // let expr = expr.resolve().unwrap(); - let expr = match expr.typecheck() { - Ok(expr) => expr, - Err(e) => { - let explain = ::std::env::args().any(|s| s == "--explain"); - if !explain { - term_painter::Color::BrightBlack.with(|| { - println!("Use \"dhall --explain\" for detailed errors"); - }); - } - ERROR_STYLE.with(|| print!("Error: ")); - println!("{}", e.type_message.description()); - if explain { - println!("{}", e.type_message); - } - println!("{}", e.current); - // FIXME Print source position - return; - } - }; + // let expr = match expr.typecheck() { + // Ok(expr) => expr, + // Err(e) => { + // // TODO: implement pretty type error printing + // // let explain = ::std::env::args().any(|s| s == "--explain"); + // // if !explain { + // // term_painter::Color::BrightBlack.with(|| { + // // println!("Use \"dhall --explain\" for detailed errors"); + // // }); + // // } + // // ERROR_STYLE.with(|| print!("Error: ")); + // // println!("{}", e.type_message.description()); + // // if explain { + // // println!("{}", e.type_message); + // // } + // // println!("{}", e.current); + // // // FIXME Print source position + // return; + // } + // }; - let expr = expr.normalize(); + // let expr = expr.normalize(); - println!("{}", expr); + // println!("{}", expr); } diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index d6c3805..18f0ca8 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -9,6 +9,7 @@ impl<'a> Typed<'a> { Normalized(normalize(self.0), self.1, self.2) } /// Pretends this expression is normalized. Use with care. + #[allow(dead_code)] pub fn skip_normalize(self) -> Normalized<'a> { Normalized( self.0.unroll().squash_embed(&|e| e.0.clone()), diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 14c2a5f..57d3deb 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -41,7 +41,7 @@ macro_rules! make_spec_test { use crate::error::{Error, Result}; use crate::expr::Parsed; -use crate::DynamicType; +use crate::traits::DynamicType; use std::path::PathBuf; #[derive(Copy, Clone)] diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index e854927..f967aa5 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -25,6 +25,7 @@ impl<'a> Resolved<'a> { type_of(dhall::subexpr!(expr: ty)) } /// Pretends this expression has been typechecked. Use with care. + #[allow(dead_code)] pub fn skip_typecheck(self) -> Typed<'a> { Typed(self.0.unnote(), None, PhantomData) } @@ -49,7 +50,7 @@ impl<'a> Normalized<'a> { } } impl<'a> Type<'a> { - pub fn as_normalized(&self) -> Result<&Normalized<'a>, TypeError> { + pub(crate) fn as_normalized(&self) -> Result<&Normalized<'a>, TypeError> { use TypeInternal::*; match &self.0 { Expr(e) => Ok(e), @@ -83,7 +84,7 @@ impl<'a> Type<'a> { }) } - pub fn const_sort() -> Self { + fn const_sort() -> Self { Normalized( rc(ExprF::Const(Const::Sort)), Some(Type(TypeInternal::SuperType)), @@ -91,7 +92,7 @@ impl<'a> Type<'a> { ) .into_type() } - pub fn const_kind() -> Self { + fn const_kind() -> Self { Normalized( rc(ExprF::Const(Const::Kind)), Some(Type::const_sort()), @@ -99,7 +100,7 @@ impl<'a> Type<'a> { ) .into_type() } - pub fn const_type() -> Self { + pub(crate) fn const_type() -> Self { Normalized( rc(ExprF::Const(Const::Type)), Some(Type::const_kind()), @@ -306,7 +307,7 @@ macro_rules! ensure_is_const { /// Type-check an expression and return the expression alongside its type if type-checking /// succeeded, or an error if type-checking failed -pub fn type_with( +fn type_with( ctx: &Context>, e: SubExpr>, ) -> Result, TypeError> { @@ -619,7 +620,7 @@ pub fn type_with( /// `typeOf` is the same as `type_with` with an empty context, meaning that the /// expression must be closed (i.e. no free variables), otherwise type-checking /// will fail. -pub fn type_of( +fn type_of( e: SubExpr>, ) -> Result, TypeError> { let ctx = Context::new(); @@ -631,7 +632,7 @@ pub fn type_of( /// The specific type error #[derive(Debug)] -pub enum TypeMessage<'a> { +pub(crate) enum TypeMessage<'a> { UnboundVariable, InvalidInputType(Normalized<'a>), InvalidOutputType(Normalized<'a>), @@ -647,8 +648,6 @@ pub enum TypeMessage<'a> { IfBranchMustBeTerm(bool, Typed<'a>), InvalidField(Label, Typed<'a>), InvalidFieldType(Label, Typed<'a>), - DuplicateAlternative(Label), - FieldCollision(Label), NotARecord(Label, Typed<'a>), MissingField(Label, Typed<'a>), BinOpTypeMismatch(BinOp, Typed<'a>), @@ -660,13 +659,13 @@ pub enum TypeMessage<'a> { /// A structured type error that includes context #[derive(Debug)] pub struct TypeError { - pub context: Context>, - pub current: SubExpr>, - pub type_message: TypeMessage<'static>, + context: Context>, + current: SubExpr>, + type_message: TypeMessage<'static>, } impl TypeError { - pub fn new( + pub(crate) fn new( context: &Context>, current: SubExpr>, type_message: TypeMessage<'static>, -- cgit v1.2.3