blob: 19bf8503c01561c5bfed82b81f6629d3503345a8 [file] [log] [blame]
//! To run this example, execute the following command from the top level of
//! this repository:
//!
//! ```sh
//! cargo run --example term
//! ```
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::termcolor::StandardStream;
use codespan_reporting::term::{self, ColorArg};
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "emit")]
pub struct Opts {
/// Configure coloring of output
#[structopt(
long = "color",
parse(try_from_str),
default_value = "auto",
possible_values = ColorArg::VARIANTS,
case_insensitive = true
)]
pub color: ColorArg,
}
fn main() -> anyhow::Result<()> {
let opts = Opts::from_args();
let mut files = SimpleFiles::new();
let file_id1 = files.add(
"Data/Nat.fun",
unindent::unindent(
"
module Data.Nat where
data Nat : Type where
zero : Nat
succ : Nat Nat
{-# BUILTIN NATRAL Nat #-}
infixl 6 _+_ _-_
_+_ : Nat Nat Nat
zero + n = n
succ n + n = succ (n + n₂)
_-_ : Nat Nat Nat
n - zero = n
zero - succ n = zero
succ n - succ n = n - n
",
),
);
let file_id2 = files.add(
"Test.fun",
unindent::unindent(
r#"
module Test where
_ : Nat
_ = 123 + "hello"
"#,
),
);
let file_id3 = files.add(
"FizzBuzz.fun",
unindent::unindent(
r#"
module FizzBuzz where
fizz : Nat String
fizz num = case (mod num 5) (mod num 3) of
0 0 => "FizzBuzz"
0 _ => "Fizz"
_ 0 => "Buzz"
_ _ => num
fizz : Nat String
fizz num =
case (mod num 5) (mod num 3) of
0 0 => "FizzBuzz"
0 _ => "Fizz"
_ 0 => "Buzz"
_ _ => num
"#,
),
);
let diagnostics = [
// Unknown builtin error
Diagnostic::error()
.with_message("unknown builtin: `NATRAL`")
.with_labels(vec![
Label::primary(file_id1, 96..102).with_message("unknown builtin")
])
.with_notes(vec![
"there is a builtin with a similar name: `NATURAL`".to_owned()
]),
// Unused parameter warning
Diagnostic::warning()
.with_message("unused parameter pattern: `n₂`")
.with_labels(vec![
Label::primary(file_id1, 285..289).with_message("unused parameter")
])
.with_notes(vec!["consider using a wildcard pattern: `_`".to_owned()]),
// Unexpected type error
Diagnostic::error()
.with_message("unexpected type in application of `_+_`")
.with_code("E0001")
.with_labels(vec![
Label::primary(file_id2, 37..44).with_message("expected `Nat`, found `String`"),
Label::secondary(file_id1, 130..155)
.with_message("based on the definition of `_+_`"),
])
.with_notes(vec![unindent::unindent(
"
expected type `Nat`
found type `String`
",
)]),
// Incompatible match clause error
Diagnostic::error()
.with_message("`case` clauses have incompatible types")
.with_code("E0308")
.with_labels(vec![
Label::primary(file_id3, 163..166).with_message("expected `String`, found `Nat`"),
Label::secondary(file_id3, 62..166)
.with_message("`case` clauses have incompatible types"),
Label::secondary(file_id3, 41..47)
.with_message("expected type `String` found here"),
])
.with_notes(vec![unindent::unindent(
"
expected type `String`
found type `Nat`
",
)]),
// Incompatible match clause error
Diagnostic::error()
.with_message("`case` clauses have incompatible types")
.with_code("E0308")
.with_labels(vec![
Label::primary(file_id3, 328..331).with_message("expected `String`, found `Nat`"),
Label::secondary(file_id3, 211..331)
.with_message("`case` clauses have incompatible types"),
Label::secondary(file_id3, 258..268)
.with_message("this is found to be of type `String`"),
Label::secondary(file_id3, 284..290)
.with_message("this is found to be of type `String`"),
Label::secondary(file_id3, 306..312)
.with_message("this is found to be of type `String`"),
Label::secondary(file_id3, 186..192)
.with_message("expected type `String` found here"),
])
.with_notes(vec![unindent::unindent(
"
expected type `String`
found type `Nat`
",
)]),
];
let writer = StandardStream::stderr(opts.color.into());
let config = codespan_reporting::term::Config::default();
for diagnostic in &diagnostics {
term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
}
Ok(())
}