Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

File diff suppressed because one or more lines are too long

408
vendor/codespan-reporting/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,408 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.11.1] - 2021-01-18
### Added
- Add `Chars::{box_drawing, ascii}` functions, the latter supporting a rustc-style of
output that only uses ASCII characters (not above U+007F) for use cases that do not allow
for box drawing characters, e.g. terminals that do not support them.
### Changed
- `Diagnostic::with_labels` and `Diagnostic::with_notes` now append additional
labels rather tan overwriting them, meaning that the documentation and behaviour match
more closely. The behaviour will only differ if you call the same builder methods
multiple times. If you call every builder method once only, nothing should change.
- `config::Chars::snippet_start` is now a String instead of a single `char`.
## [0.11.0] - 2020-11-30
There is now a [code of conduct](https://github.com/brendanzab/codespan/blob/master/CODE_OF_CONDUCT.md)
and a [contributing guide](https://github.com/brendanzab/codespan/blob/master/CONTRIBUTING.md).
Some versions were skipped to sync up with the `codespan-lsp` crate. The release
process has been changed so this should not happen again.
### Added
- If a label spans over multiple lines, not all lines are rendered.
The number of lines rendered at beginning and end is configurable separately.
- There is now a custom error type.
- There now is a medium rendering mode that is like the short rendering mode
but also shows notes from the diagnostic.
- `PartialEq` and `Eq` implementations for the `diagnostic::{Diagnostic, Label, Severity}` types.
### Changed
- All errors now use the error type `codespan_reporting::file::Error`.
This type also replaces the custom error type for `codespan-lsp`.
### Fixed
- Empty error codes are not rendered.
- The locus ("location of the diagnostic") is now computed so it is always at the first
primary label, or at the first secondary label if no primary labels are available.
- All `unwrap`s outside of tests and examples have been removed.
- Some internal improvements, including various code style improvements by using Clippy.
- Improved documentation, also mentioning how the ordering of labels is handled.
## [0.9.5] - 2020-06-24
### Changed
- Sections of source code that are marked with primary labels are now rendered
using the primary highlight color.
- Tab stops are now rendered properly.
We used to just render `\t` characters in source snippets with the same
number of spaces.
<details>
<summary>Example</summary>
For example, when rendering with a tab width of `3` we
would print:
```text
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^
```
Now we properly take into account the column of the tab character:
```text
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^
```
</details>
## [0.9.4] - 2020-05-18
### Changed
- We have made the caret rendering easier to read when there are multiple
labels on the same line. We also avoid printing trailing borders on the
final source source snippet if no notes are present.
<details>
<summary>Example</summary>
Instead of this:
```text
┌─ one_line.rs:3:5
3 │ v.push(v.pop().unwrap());
│ - first borrow later used by call
│ ---- first mutable borrow occurs here
│ ^ second mutable borrow occurs here
```
…we now render the following:
```text
┌─ one_line.rs:3:5
3 │ v.push(v.pop().unwrap());
│ - ---- ^ second mutable borrow occurs here
│ │ │
│ │ first mutable borrow occurs here
│ first borrow later used by call
```
</details>
### Fixed
- Diagnostic rendering no longer panics if label ranges are between UTF-8
character boundaries.
## [0.9.3] - 2020-04-29
### Changed
- Some panics were fixed when invalid unicode boundaries are supplied.
- Labels that marked the same span were originally rendered in reverse order.
This was a mistake! We've now fixed this.
<details>
<summary>Example</summary>
For example, this diagnostic:
```text
┌─ same_range:1:7
1 │ ::S { }
│ - Expected '('
│ ^ Unexpected '{'
```
…will now be rendered as:
```text
┌─ same_range:1:7
1 │ ::S { }
│ ^ Unexpected '{'
│ - Expected '('
```
</details>
- We've reduced the prominence of the 'locus' on source snippets by
simplifying the border and reducing the spacing around it. This is to help
focus attention on the underlined source snippet and error messages, rather
than the location, which should be a secondary focus.
<details>
<summary>Example</summary>
For example we originally rendered this:
```text
error: unknown builtin: `NATRAL`
┌── Data/Nat.fun:7:13 ───
7 │ {-# BUILTIN NATRAL Nat #-}
│ ^^^^^^ unknown builtin
= there is a builtin with a similar name: `NATURAL`
```
…and now we render this:
```text
error: unknown builtin: `NATRAL`
┌─ Data/Nat.fun:7:13
7 │ {-# BUILTIN NATRAL Nat #-}
│ ^^^^^^ unknown builtin
= there is a builtin with a similar name: `NATURAL`
```
</details>
## [0.9.2] - 2020-03-29
### Changed
- Render overlapping multiline marks on the same lines of source code.
<details>
<summary>Example</summary>
For example:
```text
error[E0308]: match arms have incompatible types
┌── codespan/src/file.rs:1:9 ───
1 │ ╭ match line_index.compare(self.last_line_index()) {
2 │ │ Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
3 │ │ Ordering::Equal => Ok(self.source_span().end()),
4 │ │ Ordering::Greater => LineIndexOutOfBoundsError {
5 │ │ given: line_index,
6 │ │ max: self.last_line_index(),
7 │ │ },
8 │ │ }
│ ╰─────────' `match` arms have incompatible types
·
2 │ Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
│ --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
3 │ Ordering::Equal => Ok(self.source_span().end()),
│ ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
4 │ Ordering::Greater => LineIndexOutOfBoundsError {
│ ╭──────────────────────────────────^
5 │ │ given: line_index,
6 │ │ max: self.last_line_index(),
7 │ │ },
│ ╰─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
= expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`
```
…is now rendered as:
```text
error[E0308]: match arms have incompatible types
┌── codespan/src/file.rs:1:9 ───
1 │ ╭ match line_index.compare(self.last_line_index()) {
2 │ │ Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
│ │ --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
3 │ │ Ordering::Equal => Ok(self.source_span().end()),
│ │ ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
4 │ │ Ordering::Greater => LineIndexOutOfBoundsError {
│ ╭─│──────────────────────────────────^
5 │ │ │ given: line_index,
6 │ │ │ max: self.last_line_index(),
7 │ │ │ },
│ ╰─│─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
8 │ │ }
│ ╰─────────' `match` arms have incompatible types
= expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`
```
</details>
## [0.9.1] - 2020-03-23
### Added
- `codespan_reporting::diagnostic::Diagnostic` now implements `Debug`.
### Changed
- Single-line labels are now rendered together, under the same source line.
<details>
<summary>Example</summary>
For example:
```text
┌── one_line.rs:3:5 ───
3 │ v.push(v.pop().unwrap());
│ - first borrow later used by call
·
3 │ v.push(v.pop().unwrap());
│ ---- first mutable borrow occurs here
·
3 │ v.push(v.pop().unwrap());
│ ^ second mutable borrow occurs here
```
…is now rendered as:
```text
┌── one_line.rs:3:5 ───
3 │ v.push(v.pop().unwrap());
│ - first borrow later used by call
│ ---- first mutable borrow occurs here
│ ^ second mutable borrow occurs here
```
</details>
## [0.9.0] - 2020-03-11
### Added
- The `codespan_reporting::files` module was added as a way to decouple
`codespan_reporting` from `codespan`.
- `codespan_reporting::files::Files` allows users to implement custom file
databases that work with `codespan_reporting`. This should make it
easier to integrate with libraries like Salsa, and also makes it less
invasive to use `codespan_reporting` on existing projects.
- `codespan_reporting::files::SimpleFile` is a simple implementation of
`codespan_reporting::files::Files` where only a single file is needed.
- `codespan_reporting::files::SimpleFiles` is a simple implementation of
`codespan_reporting::files::Files` where multiple files are needed.
### Changed
- The `codespan_reporting::diagnostic` module has been greatly revamped,
making the builder API format more nicely with rustfmt, and allowing for
multiple primary labels.
- The output of `codespan_reporting::term::emit` was improved,
with the following changes:
- labels on consecutive lines no longer render breaks between them
- source lines are rendered when there is only one line between labels
- the inner gutter of code snippets is now aligned consistently
- the outer gutter of consecutive code snippets are now aligned consistently
- `codespan_reporting::term::emit` now takes writers as a trait object (rather
than using static dispatch) in order to reduce coda bloat and improve
compile times.
- The field names in `codespan_reporting::term::Chars` were tweaked for
consistency.
### Removed
- `codespan_reporting` no longer depends on `codespan`.
Note that `codespan` can _still_ be used with `codespan_reporting`,
as `codespan::Files` now implements `codespan_reporting::files::Files`.
## [0.8.0] - 2020-02-24
## [0.7.0] - 2020-01-06
## [0.6.0] - 2019-12-18
## [0.5.0] - 2019-10-02
## [0.4.1] - 2019-08-25
## [0.4.0] - 2019-08-22
## [0.3.0] - 2019-05-01
## [0.2.1] - 2019-02-26
## [0.2.0] - 2018-10-11
[Unreleased]: https://github.com/brendanzab/codespan/compare/v0.11.1...HEAD
[0.11.1]: https://github.com/brendanzab/codespan/compare/v0.11.0..v0.11.1
[0.11.0]: https://github.com/brendanzab/codespan/compare/v0.9.5...v0.11.0
[0.9.5]: https://github.com/brendanzab/codespan/compare/v0.9.4...v0.9.5
[0.9.4]: https://github.com/brendanzab/codespan/compare/v0.9.3...v0.9.4
[0.9.3]: https://github.com/brendanzab/codespan/compare/v0.9.2...v0.9.3
[0.9.2]: https://github.com/brendanzab/codespan/compare/v0.9.1...v0.9.2
[0.9.1]: https://github.com/brendanzab/codespan/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/brendanzab/codespan/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/brendanzab/codespan/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/brendanzab/codespan/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/brendanzab/codespan/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/brendanzab/codespan/compare/v0.4.1...v0.5.0
[0.4.1]: https://github.com/brendanzab/codespan/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/brendanzab/codespan/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/brendanzab/codespan/compare/v0.2.1...v0.3.0
[0.2.1]: https://github.com/brendanzab/codespan/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/brendanzab/codespan/releases/tag/v0.2.0

554
vendor/codespan-reporting/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,554 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
dependencies = [
"anyhow",
"insta",
"lazy_static",
"peg",
"rustyline",
"serde",
"structopt",
"termcolor",
"unicode-width",
"unindent",
]
[[package]]
name = "console"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"terminal_size",
"winapi",
]
[[package]]
name = "dirs-next"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6"
dependencies = [
"cfg-if 1.0.0",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "dtoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
]
[[package]]
name = "heck"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "insta"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd354a2c8c8083d58414597a4ecada1984f9b82ea7e87eeabddc869eaf120992"
dependencies = [
"console",
"lazy_static",
"serde",
"serde_json",
"serde_yaml",
"similar",
"uuid",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "nix"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
dependencies = [
"bitflags",
"cc",
"cfg-if 0.1.10",
"libc",
]
[[package]]
name = "peg"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f76678828272f177ac33b7e2ac2e3e73cc6c1cd1e3e387928aa69562fa51367"
dependencies = [
"peg-macros",
"peg-runtime",
]
[[package]]
name = "peg-macros"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "636d60acf97633e48d266d7415a9355d4389cea327a193f87df395d88cd2b14d"
dependencies = [
"peg-runtime",
"proc-macro2",
"quote",
]
[[package]]
name = "peg-runtime"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555b1514d2d99d78150d3c799d4c357a3e2c2a8062cd108e93a06d9057629c5"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom",
"redox_syscall",
]
[[package]]
name = "rustyline"
version = "6.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0d5e7b0219a3eadd5439498525d4765c59b7c993ef0c12244865cd2d988413"
dependencies = [
"cfg-if 0.1.10",
"dirs-next",
"libc",
"log",
"memchr",
"nix",
"scopeguard",
"unicode-segmentation",
"unicode-width",
"utf8parse",
"winapi",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
dependencies = [
"dtoa",
"linked-hash-map",
"serde",
"yaml-rust",
]
[[package]]
name = "similar"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a04629d2e8ecdcf30e0188e3699ed6d50d5750d0219db146a790065fe92a897"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-segmentation"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "unindent"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"
[[package]]
name = "utf8parse"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

58
vendor/codespan-reporting/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,58 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "codespan-reporting"
version = "0.11.1"
authors = ["Brendan Zabarauskas <bjzaba@yahoo.com.au>"]
exclude = ["assets/**"]
description = "Beautiful diagnostic reporting for text-based programming languages"
homepage = "https://github.com/brendanzab/codespan"
documentation = "https://docs.rs/codespan-reporting"
readme = "../README.md"
license = "Apache-2.0"
repository = "https://github.com/brendanzab/codespan"
[dependencies.serde]
version = "1"
features = ["derive"]
optional = true
[dependencies.termcolor]
version = "1"
[dependencies.unicode-width]
version = "0.1"
[dev-dependencies.anyhow]
version = "1"
[dev-dependencies.insta]
version = "1.6.3"
[dev-dependencies.lazy_static]
version = "1.4"
[dev-dependencies.peg]
version = "0.6"
[dev-dependencies.rustyline]
version = "6"
[dev-dependencies.structopt]
version = "0.3"
[dev-dependencies.unindent]
version = "0.1"
[features]
ascii-only = []
serialization = ["serde", "serde/rc"]

View File

@@ -0,0 +1,197 @@
//! An example that shows how to implement a simple custom file database.
//! The database uses 32-bit file-ids, which could be useful for optimizing
//! memory usage.
//!
//! To run this example, execute the following command from the top level of
//! this repository:
//!
//! ```sh
//! cargo run --example custom_files
//! ```
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use std::ops::Range;
fn main() -> anyhow::Result<()> {
let mut files = files::Files::new();
let file_id0 = files.add("0.greeting", "hello world!").unwrap();
let file_id1 = files.add("1.greeting", "bye world").unwrap();
let messages = vec![
Message::UnwantedGreetings {
greetings: vec![(file_id0, 0..5), (file_id1, 0..3)],
},
Message::OverTheTopExclamations {
exclamations: vec![(file_id0, 11..12)],
},
];
let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default();
for message in &messages {
let writer = &mut writer.lock();
term::emit(writer, &config, &files, &message.to_diagnostic())?;
}
Ok(())
}
/// A module containing the file implementation
mod files {
use codespan_reporting::files;
use std::ops::Range;
/// A file that is backed by an `Arc<String>`.
#[derive(Debug, Clone)]
struct File {
/// The name of the file.
name: String,
/// The source code of the file.
source: String,
/// The starting byte indices in the source code.
line_starts: Vec<usize>,
}
impl File {
fn line_start(&self, line_index: usize) -> Result<usize, files::Error> {
use std::cmp::Ordering;
match line_index.cmp(&self.line_starts.len()) {
Ordering::Less => Ok(self
.line_starts
.get(line_index)
.expect("failed despite previous check")
.clone()),
Ordering::Equal => Ok(self.source.len()),
Ordering::Greater => Err(files::Error::LineTooLarge {
given: line_index,
max: self.line_starts.len() - 1,
}),
}
}
}
/// An opaque file identifier.
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct FileId(u32);
#[derive(Debug, Clone)]
pub struct Files {
files: Vec<File>,
}
impl Files {
/// Create a new files database.
pub fn new() -> Files {
Files { files: Vec::new() }
}
/// Add a file to the database, returning the handle that can be used to
/// refer to it again.
pub fn add(
&mut self,
name: impl Into<String>,
source: impl Into<String>,
) -> Option<FileId> {
use std::convert::TryFrom;
let file_id = FileId(u32::try_from(self.files.len()).ok()?);
let name = name.into();
let source = source.into();
let line_starts = files::line_starts(&source).collect();
self.files.push(File {
name,
line_starts,
source,
});
Some(file_id)
}
/// Get the file corresponding to the given id.
fn get(&self, file_id: FileId) -> Result<&File, files::Error> {
self.files
.get(file_id.0 as usize)
.ok_or(files::Error::FileMissing)
}
}
impl<'files> files::Files<'files> for Files {
type FileId = FileId;
type Name = &'files str;
type Source = &'files str;
fn name(&self, file_id: FileId) -> Result<&str, files::Error> {
Ok(self.get(file_id)?.name.as_ref())
}
fn source(&self, file_id: FileId) -> Result<&str, files::Error> {
Ok(&self.get(file_id)?.source)
}
fn line_index(&self, file_id: FileId, byte_index: usize) -> Result<usize, files::Error> {
self.get(file_id)?
.line_starts
.binary_search(&byte_index)
.or_else(|next_line| Ok(next_line - 1))
}
fn line_range(
&self,
file_id: FileId,
line_index: usize,
) -> Result<Range<usize>, files::Error> {
let file = self.get(file_id)?;
let line_start = file.line_start(line_index)?;
let next_line_start = file.line_start(line_index + 1)?;
Ok(line_start..next_line_start)
}
}
}
/// A Diagnostic message.
enum Message {
UnwantedGreetings {
greetings: Vec<(files::FileId, Range<usize>)>,
},
OverTheTopExclamations {
exclamations: Vec<(files::FileId, Range<usize>)>,
},
}
impl Message {
fn to_diagnostic(&self) -> Diagnostic<files::FileId> {
match self {
Message::UnwantedGreetings { greetings } => Diagnostic::error()
.with_message("greetings are not allowed")
.with_labels(
greetings
.iter()
.map(|(file_id, range)| {
Label::primary(*file_id, range.clone()).with_message("a greeting")
})
.collect(),
)
.with_notes(vec![
"found greetings!".to_owned(),
"pleas no greetings :(".to_owned(),
]),
Message::OverTheTopExclamations { exclamations } => Diagnostic::error()
.with_message("over-the-top exclamations")
.with_labels(
exclamations
.iter()
.map(|(file_id, range)| {
Label::primary(*file_id, range.clone()).with_message("an exclamation")
})
.collect(),
)
.with_notes(vec!["ridiculous!".to_owned()]),
}
}
}

View File

@@ -0,0 +1,68 @@
//! An example of using `peg` with `codespan_reporting`.
//!
//! To run this example, execute the following command from the top level of
//! this repository:
//!
//! ```sh
//! cargo run --example peg_calculator
//! ```
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use rustyline::error::ReadlineError;
use rustyline::Editor;
peg::parser! {
grammar arithmetic() for str {
rule number() -> i64
= n:$(['0'..='9']+) { n.parse().unwrap() }
pub rule calculate() -> i64 = precedence!{
x:(@) "+" y:@ { x + y }
x:(@) "-" y:@ { x - y }
"-" v:@ { - v }
--
x:(@) "*" y:@ { x * y }
x:(@) "/" y:@ { x / y }
--
x:@ "^" y:(@) { i64::pow(x, y as u32) }
v:@ "!" { (1..v+1).product() }
--
"(" v:calculate() ")" { v }
n:number() { n }
}
}
}
fn main() -> anyhow::Result<()> {
let writer = StandardStream::stderr(ColorChoice::Always);
let config = codespan_reporting::term::Config::default();
let mut editor = Editor::<()>::new();
loop {
let line = match editor.readline("> ") {
Ok(line) => line,
Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => return Ok(()),
Err(error) => return Err(error.into()),
};
match arithmetic::calculate(&line) {
Ok(number) => println!("{}", number),
Err(error) => {
let file = SimpleFile::new("<repl>", line);
let start = error.location.offset;
let diagnostic = Diagnostic::error()
.with_message("parse error")
.with_labels(vec![
Label::primary((), start..start).with_message("parse error")
])
.with_notes(vec![format!("expected: {}", error.expected)]);
term::emit(&mut writer.lock(), &config, &file, &diagnostic)?;
}
}
}
}

View File

@@ -0,0 +1,356 @@
//! Renders the preview SVG for the README.
//!
//! To update the preview, execute the following command from the top level of
//! the repository:
//!
//! ```sh
//! cargo run --example readme_preview svg > codespan-reporting/assets/readme_preview.svg
//! ```
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term::termcolor::{Color, ColorSpec, StandardStream, WriteColor};
use codespan_reporting::term::{self, ColorArg};
use std::io::{self, Write};
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "emit")]
pub enum Opts {
/// Render SVG output
Svg,
/// Render Stderr output
Stderr {
/// Configure coloring of output
#[structopt(
long = "color",
parse(try_from_str),
default_value = "auto",
possible_values = ColorArg::VARIANTS,
case_insensitive = true
)]
color: ColorArg,
},
}
fn main() -> anyhow::Result<()> {
let file = SimpleFile::new(
"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 = [Diagnostic::error()
.with_message("`case` clauses have incompatible types")
.with_code("E0308")
.with_labels(vec![
Label::primary((), 328..331).with_message("expected `String`, found `Nat`"),
Label::secondary((), 211..331).with_message("`case` clauses have incompatible types"),
Label::secondary((), 258..268).with_message("this is found to be of type `String`"),
Label::secondary((), 284..290).with_message("this is found to be of type `String`"),
Label::secondary((), 306..312).with_message("this is found to be of type `String`"),
Label::secondary((), 186..192).with_message("expected type `String` found here"),
])
.with_notes(vec![unindent::unindent(
"
expected type `String`
found type `Nat`
",
)])];
// let mut files = SimpleFiles::new();
match Opts::from_args() {
Opts::Svg => {
let mut buffer = Vec::new();
let mut writer = HtmlEscapeWriter::new(SvgWriter::new(&mut buffer));
let config = codespan_reporting::term::Config {
styles: codespan_reporting::term::Styles::with_blue(Color::Blue),
..codespan_reporting::term::Config::default()
};
for diagnostic in &diagnostics {
term::emit(&mut writer, &config, &file, &diagnostic)?;
}
let num_lines = buffer.iter().filter(|byte| **byte == b'\n').count() + 1;
let padding = 10;
let font_size = 12;
let line_spacing = 3;
let width = 882;
let height = padding + num_lines * (font_size + line_spacing) + padding;
let stdout = std::io::stdout();
let writer = &mut stdout.lock();
write!(
writer,
r#"<svg viewBox="0 0 {width} {height}" xmlns="http://www.w3.org/2000/svg">
<style>
/* https://github.com/aaron-williamson/base16-alacritty/blob/master/colors/base16-tomorrow-night-256.yml */
pre {{
background: #1d1f21;
margin: 0;
padding: {padding}px;
border-radius: 6px;
color: #ffffff;
font: {font_size}px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
}}
pre .bold {{ font-weight: bold; }}
pre .fg.black {{ color: #1d1f21; }}
pre .fg.red {{ color: #cc6666; }}
pre .fg.green {{ color: #b5bd68; }}
pre .fg.yellow {{ color: #f0c674; }}
pre .fg.blue {{ color: #81a2be; }}
pre .fg.magenta {{ color: #b294bb; }}
pre .fg.cyan {{ color: #8abeb7; }}
pre .fg.white {{ color: #c5c8c6; }}
pre .fg.black.bright {{ color: #969896; }}
pre .fg.red.bright {{ color: #cc6666; }}
pre .fg.green.bright {{ color: #b5bd68; }}
pre .fg.yellow.bright {{ color: #f0c674; }}
pre .fg.blue.bright {{ color: #81a2be; }}
pre .fg.magenta.bright {{ color: #b294bb; }}
pre .fg.cyan.bright {{ color: #8abeb7; }}
pre .fg.white.bright {{ color: #ffffff; }}
pre .bg.black {{ background-color: #1d1f21; }}
pre .bg.red {{ background-color: #cc6666; }}
pre .bg.green {{ background-color: #b5bd68; }}
pre .bg.yellow {{ background-color: #f0c674; }}
pre .bg.blue {{ background-color: #81a2be; }}
pre .bg.magenta {{ background-color: #b294bb; }}
pre .bg.cyan {{ background-color: #8abeb7; }}
pre .bg.white {{ background-color: #c5c8c6; }}
pre .bg.black.bright {{ background-color: #969896; }}
pre .bg.red.bright {{ background-color: #cc6666; }}
pre .bg.green.bright {{ background-color: #b5bd68; }}
pre .bg.yellow.bright {{ background-color: #f0c674; }}
pre .bg.blue.bright {{ background-color: #81a2be; }}
pre .bg.magenta.bright {{ background-color: #b294bb; }}
pre .bg.cyan.bright {{ background-color: #8abeb7; }}
pre .bg.white.bright {{ background-color: #ffffff; }}
</style>
<foreignObject x="0" y="0" width="{width}" height="{height}">
<div xmlns="http://www.w3.org/1999/xhtml">
<pre>"#,
padding = padding,
font_size = font_size,
width = width,
height = height,
)?;
writer.write_all(&buffer)?;
write!(
writer,
"</pre>
</div>
</foreignObject>
</svg>
"
)?;
}
Opts::Stderr { color } => {
let writer = StandardStream::stderr(color.into());
let config = codespan_reporting::term::Config::default();
for diagnostic in &diagnostics {
term::emit(&mut writer.lock(), &config, &file, &diagnostic)?;
}
}
}
Ok(())
}
/// Rudimentary HTML escaper which performs the following conversions:
///
/// - `<` ⇒ `&lt;`
/// - `>` ⇒ `&gt;`
/// - `&` ⇒ `&amp;`
pub struct HtmlEscapeWriter<W> {
upstream: W,
}
impl<W> HtmlEscapeWriter<W> {
pub fn new(upstream: W) -> HtmlEscapeWriter<W> {
HtmlEscapeWriter { upstream }
}
}
impl<W: Write> Write for HtmlEscapeWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let mut last_term = 0usize;
for (i, byte) in buf.iter().enumerate() {
let escape = match byte {
b'<' => &b"&lt;"[..],
b'>' => &b"&gt;"[..],
b'&' => &b"&amp;"[..],
_ => continue,
};
self.upstream.write_all(&buf[last_term..i])?;
last_term = i + 1;
self.upstream.write_all(escape)?;
}
self.upstream.write_all(&buf[last_term..])?;
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
self.upstream.flush()
}
}
impl<W: WriteColor> WriteColor for HtmlEscapeWriter<W> {
fn supports_color(&self) -> bool {
self.upstream.supports_color()
}
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
self.upstream.set_color(spec)
}
fn reset(&mut self) -> io::Result<()> {
self.upstream.reset()
}
}
pub struct SvgWriter<W> {
upstream: W,
color: ColorSpec,
}
impl<W> SvgWriter<W> {
pub fn new(upstream: W) -> SvgWriter<W> {
SvgWriter {
upstream,
color: ColorSpec::new(),
}
}
}
impl<W: Write> Write for SvgWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.upstream.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.upstream.flush()
}
}
impl<W: Write> WriteColor for SvgWriter<W> {
fn supports_color(&self) -> bool {
true
}
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
#![allow(unused_assignments)]
if self.color == *spec {
return Ok(());
} else {
if !self.color.is_none() {
write!(self, "</span>")?;
}
self.color = spec.clone();
}
if spec.is_none() {
write!(self, "</span>")?;
return Ok(());
} else {
write!(self, "<span class=\"")?;
}
let mut first = true;
fn write_first<W: Write>(first: bool, writer: &mut SvgWriter<W>) -> io::Result<bool> {
if !first {
write!(writer, " ")?;
}
Ok(false)
};
fn write_color<W: Write>(color: &Color, writer: &mut SvgWriter<W>) -> io::Result<()> {
match color {
Color::Black => write!(writer, "black"),
Color::Blue => write!(writer, "blue"),
Color::Green => write!(writer, "green"),
Color::Red => write!(writer, "red"),
Color::Cyan => write!(writer, "cyan"),
Color::Magenta => write!(writer, "magenta"),
Color::Yellow => write!(writer, "yellow"),
Color::White => write!(writer, "white"),
// TODO: other colors
_ => Ok(()),
}
};
if let Some(fg) = spec.fg() {
first = write_first(first, self)?;
write!(self, "fg ")?;
write_color(fg, self)?;
}
if let Some(bg) = spec.bg() {
first = write_first(first, self)?;
write!(self, "bg ")?;
write_color(bg, self)?;
}
if spec.bold() {
first = write_first(first, self)?;
write!(self, "bold")?;
}
if spec.underline() {
first = write_first(first, self)?;
write!(self, "underline")?;
}
if spec.intense() {
first = write_first(first, self)?;
write!(self, "bright")?;
}
write!(self, "\">")?;
Ok(())
}
fn reset(&mut self) -> io::Result<()> {
let color = self.color.clone();
if color != ColorSpec::new() {
write!(self, "</span>")?;
self.color = ColorSpec::new();
}
Ok(())
}
}

View File

@@ -0,0 +1,105 @@
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFile;
use codespan_reporting::term::termcolor::StandardStream;
use codespan_reporting::term::{self, ColorArg};
use std::ops::Range;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(name = "emit")]
pub struct Opts {
#[structopt(long = "color",
parse(try_from_str),
default_value = "auto",
possible_values = ColorArg::VARIANTS,
case_insensitive = true
)]
color: ColorArg,
}
fn main() -> anyhow::Result<()> {
let file = SimpleFile::new(
"main.rs",
unindent::unindent(
r#"
fn main() {
let foo: i32 = "hello, world";
foo += 1;
}
"#,
),
);
let errors = [
Error::MismatchType(
Item::new(20..23, "i32"),
Item::new(31..45, "\"hello, world\""),
),
Error::MutatingImmutable(Item::new(20..23, "foo"), Item::new(51..59, "foo += 1")),
];
let opts = Opts::from_args();
let writer = StandardStream::stderr(opts.color.into());
let config = codespan_reporting::term::Config::default();
for diagnostic in errors.iter().map(Error::report) {
term::emit(&mut writer.lock(), &config, &file, &diagnostic)?;
}
Ok(())
}
/// An error enum that represent all possible errors within your program
enum Error {
MismatchType(Item, Item),
MutatingImmutable(Item, Item),
}
impl Error {
fn report(&self) -> Diagnostic<()> {
match self {
Error::MismatchType(left, right) => Diagnostic::error()
.with_code("E0308")
.with_message("mismatch types")
.with_labels(vec![
Label::primary((), right.range.clone()).with_message(format!(
"Expected `{}`, found: `{}`",
left.content, right.content,
)),
Label::secondary((), left.range.clone()).with_message("expected due to this"),
]),
Error::MutatingImmutable(original, mutating) => Diagnostic::error()
.with_code("E0384")
.with_message(format!(
"cannot mutate immutable variable `{}`",
original.content,
))
.with_labels(vec![
Label::secondary((), original.range.clone()).with_message(unindent::unindent(
&format!(
r#"
first assignment to `{0}`
help: make this binding mutable: `mut {0}`
"#,
original.content,
),
)),
Label::primary((), mutating.range.clone())
.with_message("cannot assign twice to immutable variable"),
]),
}
}
}
/// An item in the source code to be used in the `Error` enum.
/// In a more complex program it could also contain a `files::FileId` to handle errors that occur inside multiple files.
struct Item {
range: Range<usize>,
content: String,
}
impl Item {
fn new(range: Range<usize>, content: impl Into<String>) -> Item {
let content = content.into();
Item { range, content }
}
}

View File

@@ -0,0 +1,175 @@
//! 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(())
}

View File

@@ -0,0 +1,209 @@
//! Diagnostic data structures.
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::ops::Range;
/// A severity level for diagnostic messages.
///
/// These are ordered in the following way:
///
/// ```rust
/// use codespan_reporting::diagnostic::Severity;
///
/// assert!(Severity::Bug > Severity::Error);
/// assert!(Severity::Error > Severity::Warning);
/// assert!(Severity::Warning > Severity::Note);
/// assert!(Severity::Note > Severity::Help);
/// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Severity {
/// An unexpected bug.
Bug,
/// An error.
Error,
/// A warning.
Warning,
/// A note.
Note,
/// A help message.
Help,
}
impl Severity {
/// We want bugs to be the maximum severity, errors next, etc...
fn to_cmp_int(self) -> u8 {
match self {
Severity::Bug => 5,
Severity::Error => 4,
Severity::Warning => 3,
Severity::Note => 2,
Severity::Help => 1,
}
}
}
impl PartialOrd for Severity {
fn partial_cmp(&self, other: &Severity) -> Option<std::cmp::Ordering> {
u8::partial_cmp(&self.to_cmp_int(), &other.to_cmp_int())
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum LabelStyle {
/// Labels that describe the primary cause of a diagnostic.
Primary,
/// Labels that provide additional context for a diagnostic.
Secondary,
}
/// A label describing an underlined region of code associated with a diagnostic.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Label<FileId> {
/// The style of the label.
pub style: LabelStyle,
/// The file that we are labelling.
pub file_id: FileId,
/// The range in bytes we are going to include in the final snippet.
pub range: Range<usize>,
/// An optional message to provide some additional information for the
/// underlined code. These should not include line breaks.
pub message: String,
}
impl<FileId> Label<FileId> {
/// Create a new label.
pub fn new(
style: LabelStyle,
file_id: FileId,
range: impl Into<Range<usize>>,
) -> Label<FileId> {
Label {
style,
file_id,
range: range.into(),
message: String::new(),
}
}
/// Create a new label with a style of [`LabelStyle::Primary`].
///
/// [`LabelStyle::Primary`]: LabelStyle::Primary
pub fn primary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
Label::new(LabelStyle::Primary, file_id, range)
}
/// Create a new label with a style of [`LabelStyle::Secondary`].
///
/// [`LabelStyle::Secondary`]: LabelStyle::Secondary
pub fn secondary(file_id: FileId, range: impl Into<Range<usize>>) -> Label<FileId> {
Label::new(LabelStyle::Secondary, file_id, range)
}
/// Add a message to the diagnostic.
pub fn with_message(mut self, message: impl Into<String>) -> Label<FileId> {
self.message = message.into();
self
}
}
/// Represents a diagnostic message that can provide information like errors and
/// warnings to the user.
///
/// The position of a Diagnostic is considered to be the position of the [`Label`] that has the earliest starting position and has the highest style which appears in all the labels of the diagnostic.
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Diagnostic<FileId> {
/// The overall severity of the diagnostic
pub severity: Severity,
/// An optional code that identifies this diagnostic.
pub code: Option<String>,
/// The main message associated with this diagnostic.
///
/// These should not include line breaks, and in order support the 'short'
/// diagnostic display mod, the message should be specific enough to make
/// sense on its own, without additional context provided by labels and notes.
pub message: String,
/// Source labels that describe the cause of the diagnostic.
/// The order of the labels inside the vector does not have any meaning.
/// The labels are always arranged in the order they appear in the source code.
pub labels: Vec<Label<FileId>>,
/// Notes that are associated with the primary cause of the diagnostic.
/// These can include line breaks for improved formatting.
pub notes: Vec<String>,
}
impl<FileId> Diagnostic<FileId> {
/// Create a new diagnostic.
pub fn new(severity: Severity) -> Diagnostic<FileId> {
Diagnostic {
severity,
code: None,
message: String::new(),
labels: Vec::new(),
notes: Vec::new(),
}
}
/// Create a new diagnostic with a severity of [`Severity::Bug`].
///
/// [`Severity::Bug`]: Severity::Bug
pub fn bug() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Bug)
}
/// Create a new diagnostic with a severity of [`Severity::Error`].
///
/// [`Severity::Error`]: Severity::Error
pub fn error() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Error)
}
/// Create a new diagnostic with a severity of [`Severity::Warning`].
///
/// [`Severity::Warning`]: Severity::Warning
pub fn warning() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Warning)
}
/// Create a new diagnostic with a severity of [`Severity::Note`].
///
/// [`Severity::Note`]: Severity::Note
pub fn note() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Note)
}
/// Create a new diagnostic with a severity of [`Severity::Help`].
///
/// [`Severity::Help`]: Severity::Help
pub fn help() -> Diagnostic<FileId> {
Diagnostic::new(Severity::Help)
}
/// Set the error code of the diagnostic.
pub fn with_code(mut self, code: impl Into<String>) -> Diagnostic<FileId> {
self.code = Some(code.into());
self
}
/// Set the message of the diagnostic.
pub fn with_message(mut self, message: impl Into<String>) -> Diagnostic<FileId> {
self.message = message.into();
self
}
/// Add some labels to the diagnostic.
pub fn with_labels(mut self, mut labels: Vec<Label<FileId>>) -> Diagnostic<FileId> {
self.labels.append(&mut labels);
self
}
/// Add some notes to the diagnostic.
pub fn with_notes(mut self, mut notes: Vec<String>) -> Diagnostic<FileId> {
self.notes.append(&mut notes);
self
}
}

443
vendor/codespan-reporting/src/files.rs vendored Normal file
View File

@@ -0,0 +1,443 @@
//! Source file support for diagnostic reporting.
//!
//! The main trait defined in this module is the [`Files`] trait, which provides
//! provides the minimum amount of functionality required for printing [`Diagnostics`]
//! with the [`term::emit`] function.
//!
//! Simple implementations of this trait are implemented:
//!
//! - [`SimpleFile`]: For single-file use-cases
//! - [`SimpleFiles`]: For multi-file use-cases
//!
//! These data structures provide a pretty minimal API, however,
//! so end-users are encouraged to create their own implementations for their
//! own specific use-cases, such as an implementation that accesses the file
//! system directly (and caches the line start locations), or an implementation
//! using an incremental compilation library like [`salsa`].
//!
//! [`term::emit`]: crate::term::emit
//! [`Diagnostics`]: crate::diagnostic::Diagnostic
//! [`Files`]: Files
//! [`SimpleFile`]: SimpleFile
//! [`SimpleFiles`]: SimpleFiles
//!
//! [`salsa`]: https://crates.io/crates/salsa
use std::ops::Range;
/// An enum representing an error that happened while looking up a file or a piece of content in that file.
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
/// A required file is not in the file database.
FileMissing,
/// The file is present, but does not contain the specified byte index.
IndexTooLarge { given: usize, max: usize },
/// The file is present, but does not contain the specified line index.
LineTooLarge { given: usize, max: usize },
/// The file is present and contains the specified line index, but the line does not contain the specified column index.
ColumnTooLarge { given: usize, max: usize },
/// The given index is contained in the file, but is not a boundary of a UTF-8 code point.
InvalidCharBoundary { given: usize },
/// There was a error while doing IO.
Io(std::io::Error),
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Error {
Error::Io(err)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::FileMissing => write!(f, "file missing"),
Error::IndexTooLarge { given, max } => {
write!(f, "invalid index {}, maximum index is {}", given, max)
}
Error::LineTooLarge { given, max } => {
write!(f, "invalid line {}, maximum line is {}", given, max)
}
Error::ColumnTooLarge { given, max } => {
write!(f, "invalid column {}, maximum column {}", given, max)
}
Error::InvalidCharBoundary { .. } => write!(f, "index is not a code point boundary"),
Error::Io(err) => write!(f, "{}", err),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match &self {
Error::Io(err) => Some(err),
_ => None,
}
}
}
/// A minimal interface for accessing source files when rendering diagnostics.
///
/// A lifetime parameter `'a` is provided to allow any of the returned values to returned by reference.
/// This is to workaround the lack of higher kinded lifetime parameters.
/// This can be ignored if this is not needed, however.
pub trait Files<'a> {
/// A unique identifier for files in the file provider. This will be used
/// for rendering `diagnostic::Label`s in the corresponding source files.
type FileId: 'a + Copy + PartialEq;
/// The user-facing name of a file, to be displayed in diagnostics.
type Name: 'a + std::fmt::Display;
/// The source code of a file.
type Source: 'a + AsRef<str>;
/// The user-facing name of a file.
fn name(&'a self, id: Self::FileId) -> Result<Self::Name, Error>;
/// The source code of a file.
fn source(&'a self, id: Self::FileId) -> Result<Self::Source, Error>;
/// The index of the line at the given byte index.
/// If the byte index is past the end of the file, returns the maximum line index in the file.
/// This means that this function only fails if the file is not present.
///
/// # Note for trait implementors
///
/// This can be implemented efficiently by performing a binary search over
/// a list of line starts that was computed by calling the [`line_starts`]
/// function that is exported from the [`files`] module. It might be useful
/// to pre-compute and cache these line starts.
///
/// [`line_starts`]: crate::files::line_starts
/// [`files`]: crate::files
fn line_index(&'a self, id: Self::FileId, byte_index: usize) -> Result<usize, Error>;
/// The user-facing line number at the given line index.
/// It is not necessarily checked that the specified line index
/// is actually in the file.
///
/// # Note for trait implementors
///
/// This is usually 1-indexed from the beginning of the file, but
/// can be useful for implementing something like the
/// [C preprocessor's `#line` macro][line-macro].
///
/// [line-macro]: https://en.cppreference.com/w/c/preprocessor/line
#[allow(unused_variables)]
fn line_number(&'a self, id: Self::FileId, line_index: usize) -> Result<usize, Error> {
Ok(line_index + 1)
}
/// The user-facing column number at the given line index and byte index.
///
/// # Note for trait implementors
///
/// This is usually 1-indexed from the the start of the line.
/// A default implementation is provided, based on the [`column_index`]
/// function that is exported from the [`files`] module.
///
/// [`files`]: crate::files
/// [`column_index`]: crate::files::column_index
fn column_number(
&'a self,
id: Self::FileId,
line_index: usize,
byte_index: usize,
) -> Result<usize, Error> {
let source = self.source(id)?;
let line_range = self.line_range(id, line_index)?;
let column_index = column_index(source.as_ref(), line_range, byte_index);
Ok(column_index + 1)
}
/// Convenience method for returning line and column number at the given
/// byte index in the file.
fn location(&'a self, id: Self::FileId, byte_index: usize) -> Result<Location, Error> {
let line_index = self.line_index(id, byte_index)?;
Ok(Location {
line_number: self.line_number(id, line_index)?,
column_number: self.column_number(id, line_index, byte_index)?,
})
}
/// The byte range of line in the source of the file.
fn line_range(&'a self, id: Self::FileId, line_index: usize) -> Result<Range<usize>, Error>;
}
/// A user-facing location in a source file.
///
/// Returned by [`Files::location`].
///
/// [`Files::location`]: Files::location
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Location {
/// The user-facing line number.
pub line_number: usize,
/// The user-facing column number.
pub column_number: usize,
}
/// The column index at the given byte index in the source file.
/// This is the number of characters to the given byte index.
///
/// If the byte index is smaller than the start of the line, then `0` is returned.
/// If the byte index is past the end of the line, the column index of the last
/// character `+ 1` is returned.
///
/// # Example
///
/// ```rust
/// use codespan_reporting::files;
///
/// let source = "\n\n🗻∈🌏\n\n";
///
/// assert_eq!(files::column_index(source, 0..1, 0), 0);
/// assert_eq!(files::column_index(source, 2..13, 0), 0);
/// assert_eq!(files::column_index(source, 2..13, 2 + 0), 0);
/// assert_eq!(files::column_index(source, 2..13, 2 + 1), 0);
/// assert_eq!(files::column_index(source, 2..13, 2 + 4), 1);
/// assert_eq!(files::column_index(source, 2..13, 2 + 8), 2);
/// assert_eq!(files::column_index(source, 2..13, 2 + 10), 2);
/// assert_eq!(files::column_index(source, 2..13, 2 + 11), 3);
/// assert_eq!(files::column_index(source, 2..13, 2 + 12), 3);
/// ```
pub fn column_index(source: &str, line_range: Range<usize>, byte_index: usize) -> usize {
let end_index = std::cmp::min(byte_index, std::cmp::min(line_range.end, source.len()));
(line_range.start..end_index)
.filter(|byte_index| source.is_char_boundary(byte_index + 1))
.count()
}
/// Return the starting byte index of each line in the source string.
///
/// This can make it easier to implement [`Files::line_index`] by allowing
/// implementors of [`Files`] to pre-compute the line starts, then search for
/// the corresponding line range, as shown in the example below.
///
/// [`Files`]: Files
/// [`Files::line_index`]: Files::line_index
///
/// # Example
///
/// ```rust
/// use codespan_reporting::files;
///
/// let source = "foo\nbar\r\n\nbaz";
/// let line_starts: Vec<_> = files::line_starts(source).collect();
///
/// assert_eq!(
/// line_starts,
/// [
/// 0, // "foo\n"
/// 4, // "bar\r\n"
/// 9, // ""
/// 10, // "baz"
/// ],
/// );
///
/// fn line_index(line_starts: &[usize], byte_index: usize) -> Option<usize> {
/// match line_starts.binary_search(&byte_index) {
/// Ok(line) => Some(line),
/// Err(next_line) => Some(next_line - 1),
/// }
/// }
///
/// assert_eq!(line_index(&line_starts, 5), Some(1));
/// ```
// NOTE: this is copied in `codespan::file::line_starts` and should be kept in sync.
pub fn line_starts<'source>(source: &'source str) -> impl 'source + Iterator<Item = usize> {
std::iter::once(0).chain(source.match_indices('\n').map(|(i, _)| i + 1))
}
/// A file database that contains a single source file.
///
/// Because there is only single file in this database we use `()` as a [`FileId`].
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
///
/// [`FileId`]: Files::FileId
#[derive(Debug, Clone)]
pub struct SimpleFile<Name, Source> {
/// The name of the file.
name: Name,
/// The source code of the file.
source: Source,
/// The starting byte indices in the source code.
line_starts: Vec<usize>,
}
impl<Name, Source> SimpleFile<Name, Source>
where
Name: std::fmt::Display,
Source: AsRef<str>,
{
/// Create a new source file.
pub fn new(name: Name, source: Source) -> SimpleFile<Name, Source> {
SimpleFile {
name,
line_starts: line_starts(source.as_ref()).collect(),
source,
}
}
/// Return the name of the file.
pub fn name(&self) -> &Name {
&self.name
}
/// Return the source of the file.
pub fn source(&self) -> &Source {
&self.source
}
/// Return the starting byte index of the line with the specified line index.
/// Convenience method that already generates errors if necessary.
fn line_start(&self, line_index: usize) -> Result<usize, Error> {
use std::cmp::Ordering;
match line_index.cmp(&self.line_starts.len()) {
Ordering::Less => Ok(self
.line_starts
.get(line_index)
.cloned()
.expect("failed despite previous check")),
Ordering::Equal => Ok(self.source.as_ref().len()),
Ordering::Greater => Err(Error::LineTooLarge {
given: line_index,
max: self.line_starts.len() - 1,
}),
}
}
}
impl<'a, Name, Source> Files<'a> for SimpleFile<Name, Source>
where
Name: 'a + std::fmt::Display + Clone,
Source: 'a + AsRef<str>,
{
type FileId = ();
type Name = Name;
type Source = &'a str;
fn name(&self, (): ()) -> Result<Name, Error> {
Ok(self.name.clone())
}
fn source(&self, (): ()) -> Result<&str, Error> {
Ok(self.source.as_ref())
}
fn line_index(&self, (): (), byte_index: usize) -> Result<usize, Error> {
Ok(self
.line_starts
.binary_search(&byte_index)
.unwrap_or_else(|next_line| next_line - 1))
}
fn line_range(&self, (): (), line_index: usize) -> Result<Range<usize>, Error> {
let line_start = self.line_start(line_index)?;
let next_line_start = self.line_start(line_index + 1)?;
Ok(line_start..next_line_start)
}
}
/// A file database that can store multiple source files.
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
/// It is a glorified `Vec<SimpleFile>` that implements the `Files` trait.
#[derive(Debug, Clone)]
pub struct SimpleFiles<Name, Source> {
files: Vec<SimpleFile<Name, Source>>,
}
impl<Name, Source> SimpleFiles<Name, Source>
where
Name: std::fmt::Display,
Source: AsRef<str>,
{
/// Create a new files database.
pub fn new() -> SimpleFiles<Name, Source> {
SimpleFiles { files: Vec::new() }
}
/// Add a file to the database, returning the handle that can be used to
/// refer to it again.
pub fn add(&mut self, name: Name, source: Source) -> usize {
let file_id = self.files.len();
self.files.push(SimpleFile::new(name, source));
file_id
}
/// Get the file corresponding to the given id.
pub fn get(&self, file_id: usize) -> Result<&SimpleFile<Name, Source>, Error> {
self.files.get(file_id).ok_or(Error::FileMissing)
}
}
impl<'a, Name, Source> Files<'a> for SimpleFiles<Name, Source>
where
Name: 'a + std::fmt::Display + Clone,
Source: 'a + AsRef<str>,
{
type FileId = usize;
type Name = Name;
type Source = &'a str;
fn name(&self, file_id: usize) -> Result<Name, Error> {
Ok(self.get(file_id)?.name().clone())
}
fn source(&self, file_id: usize) -> Result<&str, Error> {
Ok(self.get(file_id)?.source().as_ref())
}
fn line_index(&self, file_id: usize, byte_index: usize) -> Result<usize, Error> {
self.get(file_id)?.line_index((), byte_index)
}
fn line_range(&self, file_id: usize, line_index: usize) -> Result<Range<usize>, Error> {
self.get(file_id)?.line_range((), line_index)
}
}
#[cfg(test)]
mod test {
use super::*;
const TEST_SOURCE: &str = "foo\nbar\r\n\nbaz";
#[test]
fn line_starts() {
let file = SimpleFile::new("test", TEST_SOURCE);
assert_eq!(
file.line_starts,
[
0, // "foo\n"
4, // "bar\r\n"
9, // ""
10, // "baz"
],
);
}
#[test]
fn line_span_sources() {
let file = SimpleFile::new("test", TEST_SOURCE);
let line_sources = (0..4)
.map(|line| {
let line_range = file.line_range((), line).unwrap();
&file.source[line_range]
})
.collect::<Vec<_>>();
assert_eq!(line_sources, ["foo\n", "bar\r\n", "\n", "baz"]);
}
}

7
vendor/codespan-reporting/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,7 @@
//! Diagnostic reporting support for the codespan crate.
#![forbid(unsafe_code)]
pub mod diagnostic;
pub mod files;
pub mod term;

121
vendor/codespan-reporting/src/term.rs vendored Normal file
View File

@@ -0,0 +1,121 @@
//! Terminal back-end for emitting diagnostics.
use std::str::FromStr;
use termcolor::{ColorChoice, WriteColor};
use crate::diagnostic::Diagnostic;
use crate::files::Files;
mod config;
mod renderer;
mod views;
pub use termcolor;
pub use self::config::{Chars, Config, DisplayStyle, Styles};
/// A command line argument that configures the coloring of the output.
///
/// This can be used with command line argument parsers like [`clap`] or [`structopt`].
///
/// [`clap`]: https://crates.io/crates/clap
/// [`structopt`]: https://crates.io/crates/structopt
///
/// # Example
///
/// ```rust
/// use codespan_reporting::term::termcolor::StandardStream;
/// use codespan_reporting::term::ColorArg;
/// use structopt::StructOpt;
///
/// #[derive(Debug, StructOpt)]
/// #[structopt(name = "groovey-app")]
/// pub struct Opts {
/// /// Configure coloring of output
/// #[structopt(
/// long = "color",
/// default_value = "auto",
/// possible_values = ColorArg::VARIANTS,
/// case_insensitive = true,
/// )]
/// pub color: ColorArg,
/// }
///
/// let opts = Opts::from_args();
/// let writer = StandardStream::stderr(opts.color.into());
/// ```
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ColorArg(pub ColorChoice);
impl ColorArg {
/// Allowed values the argument.
///
/// This is useful for generating documentation via [`clap`] or `structopt`'s
/// `possible_values` configuration.
///
/// [`clap`]: https://crates.io/crates/clap
/// [`structopt`]: https://crates.io/crates/structopt
pub const VARIANTS: &'static [&'static str] = &["auto", "always", "ansi", "never"];
}
impl FromStr for ColorArg {
type Err = &'static str;
fn from_str(src: &str) -> Result<ColorArg, &'static str> {
match src {
_ if src.eq_ignore_ascii_case("auto") => Ok(ColorArg(ColorChoice::Auto)),
_ if src.eq_ignore_ascii_case("always") => Ok(ColorArg(ColorChoice::Always)),
_ if src.eq_ignore_ascii_case("ansi") => Ok(ColorArg(ColorChoice::AlwaysAnsi)),
_ if src.eq_ignore_ascii_case("never") => Ok(ColorArg(ColorChoice::Never)),
_ => Err("valid values: auto, always, ansi, never"),
}
}
}
impl Into<ColorChoice> for ColorArg {
fn into(self) -> ColorChoice {
self.0
}
}
/// Emit a diagnostic using the given writer, context, config, and files.
///
/// The return value covers all error cases. These error case can arise if:
/// * a file was removed from the file database.
/// * a file was changed so that it is too small to have an index
/// * IO fails
pub fn emit<'files, F: Files<'files>>(
writer: &mut dyn WriteColor,
config: &Config,
files: &'files F,
diagnostic: &Diagnostic<F::FileId>,
) -> Result<(), super::files::Error> {
use self::renderer::Renderer;
use self::views::{RichDiagnostic, ShortDiagnostic};
let mut renderer = Renderer::new(writer, config);
match config.display_style {
DisplayStyle::Rich => RichDiagnostic::new(diagnostic, config).render(files, &mut renderer),
DisplayStyle::Medium => ShortDiagnostic::new(diagnostic, true).render(files, &mut renderer),
DisplayStyle::Short => ShortDiagnostic::new(diagnostic, false).render(files, &mut renderer),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::diagnostic::Label;
use crate::files::SimpleFiles;
#[test]
fn unsized_emit() {
let mut files = SimpleFiles::new();
let id = files.add("test", "");
let mut writer = termcolor::NoColor::new(Vec::<u8>::new());
let diagnostic = Diagnostic::bug().with_labels(vec![Label::primary(id, 0..0)]);
emit(&mut writer, &Config::default(), &files, &diagnostic).unwrap();
}
}

View File

@@ -0,0 +1,321 @@
use termcolor::{Color, ColorSpec};
use crate::diagnostic::{LabelStyle, Severity};
/// Configures how a diagnostic is rendered.
#[derive(Clone, Debug)]
pub struct Config {
/// The display style to use when rendering diagnostics.
/// Defaults to: [`DisplayStyle::Rich`].
///
/// [`DisplayStyle::Rich`]: DisplayStyle::Rich
pub display_style: DisplayStyle,
/// Column width of tabs.
/// Defaults to: `4`.
pub tab_width: usize,
/// Styles to use when rendering the diagnostic.
pub styles: Styles,
/// Characters to use when rendering the diagnostic.
pub chars: Chars,
/// The minimum number of lines to be shown after the line on which a multiline [`Label`] begins.
///
/// Defaults to: `3`.
///
/// [`Label`]: crate::diagnostic::Label
pub start_context_lines: usize,
/// The minimum number of lines to be shown before the line on which a multiline [`Label`] ends.
///
/// Defaults to: `1`.
///
/// [`Label`]: crate::diagnostic::Label
pub end_context_lines: usize,
}
impl Default for Config {
fn default() -> Config {
Config {
display_style: DisplayStyle::Rich,
tab_width: 4,
styles: Styles::default(),
chars: Chars::default(),
start_context_lines: 3,
end_context_lines: 1,
}
}
}
/// The display style to use when rendering diagnostics.
#[derive(Clone, Debug)]
pub enum DisplayStyle {
/// Output a richly formatted diagnostic, with source code previews.
///
/// ```text
/// error[E0001]: unexpected type in `+` application
/// ┌─ test:2:9
/// │
/// 2 │ (+ test "")
/// │ ^^ expected `Int` but found `String`
/// │
/// = expected type `Int`
/// found type `String`
///
/// error[E0002]: Bad config found
///
/// ```
Rich,
/// Output a condensed diagnostic, with a line number, severity, message and notes (if any).
///
/// ```text
/// test:2:9: error[E0001]: unexpected type in `+` application
/// = expected type `Int`
/// found type `String`
///
/// error[E0002]: Bad config found
/// ```
Medium,
/// Output a short diagnostic, with a line number, severity, and message.
///
/// ```text
/// test:2:9: error[E0001]: unexpected type in `+` application
/// error[E0002]: Bad config found
/// ```
Short,
}
/// Styles to use when rendering the diagnostic.
#[derive(Clone, Debug)]
pub struct Styles {
/// The style to use when rendering bug headers.
/// Defaults to `fg:red bold intense`.
pub header_bug: ColorSpec,
/// The style to use when rendering error headers.
/// Defaults to `fg:red bold intense`.
pub header_error: ColorSpec,
/// The style to use when rendering warning headers.
/// Defaults to `fg:yellow bold intense`.
pub header_warning: ColorSpec,
/// The style to use when rendering note headers.
/// Defaults to `fg:green bold intense`.
pub header_note: ColorSpec,
/// The style to use when rendering help headers.
/// Defaults to `fg:cyan bold intense`.
pub header_help: ColorSpec,
/// The style to use when the main diagnostic message.
/// Defaults to `bold intense`.
pub header_message: ColorSpec,
/// The style to use when rendering bug labels.
/// Defaults to `fg:red`.
pub primary_label_bug: ColorSpec,
/// The style to use when rendering error labels.
/// Defaults to `fg:red`.
pub primary_label_error: ColorSpec,
/// The style to use when rendering warning labels.
/// Defaults to `fg:yellow`.
pub primary_label_warning: ColorSpec,
/// The style to use when rendering note labels.
/// Defaults to `fg:green`.
pub primary_label_note: ColorSpec,
/// The style to use when rendering help labels.
/// Defaults to `fg:cyan`.
pub primary_label_help: ColorSpec,
/// The style to use when rendering secondary labels.
/// Defaults `fg:blue` (or `fg:cyan` on windows).
pub secondary_label: ColorSpec,
/// The style to use when rendering the line numbers.
/// Defaults `fg:blue` (or `fg:cyan` on windows).
pub line_number: ColorSpec,
/// The style to use when rendering the source code borders.
/// Defaults `fg:blue` (or `fg:cyan` on windows).
pub source_border: ColorSpec,
/// The style to use when rendering the note bullets.
/// Defaults `fg:blue` (or `fg:cyan` on windows).
pub note_bullet: ColorSpec,
}
impl Styles {
/// The style used to mark a header at a given severity.
pub fn header(&self, severity: Severity) -> &ColorSpec {
match severity {
Severity::Bug => &self.header_bug,
Severity::Error => &self.header_error,
Severity::Warning => &self.header_warning,
Severity::Note => &self.header_note,
Severity::Help => &self.header_help,
}
}
/// The style used to mark a primary or secondary label at a given severity.
pub fn label(&self, severity: Severity, label_style: LabelStyle) -> &ColorSpec {
match (label_style, severity) {
(LabelStyle::Primary, Severity::Bug) => &self.primary_label_bug,
(LabelStyle::Primary, Severity::Error) => &self.primary_label_error,
(LabelStyle::Primary, Severity::Warning) => &self.primary_label_warning,
(LabelStyle::Primary, Severity::Note) => &self.primary_label_note,
(LabelStyle::Primary, Severity::Help) => &self.primary_label_help,
(LabelStyle::Secondary, _) => &self.secondary_label,
}
}
#[doc(hidden)]
pub fn with_blue(blue: Color) -> Styles {
let header = ColorSpec::new().set_bold(true).set_intense(true).clone();
Styles {
header_bug: header.clone().set_fg(Some(Color::Red)).clone(),
header_error: header.clone().set_fg(Some(Color::Red)).clone(),
header_warning: header.clone().set_fg(Some(Color::Yellow)).clone(),
header_note: header.clone().set_fg(Some(Color::Green)).clone(),
header_help: header.clone().set_fg(Some(Color::Cyan)).clone(),
header_message: header,
primary_label_bug: ColorSpec::new().set_fg(Some(Color::Red)).clone(),
primary_label_error: ColorSpec::new().set_fg(Some(Color::Red)).clone(),
primary_label_warning: ColorSpec::new().set_fg(Some(Color::Yellow)).clone(),
primary_label_note: ColorSpec::new().set_fg(Some(Color::Green)).clone(),
primary_label_help: ColorSpec::new().set_fg(Some(Color::Cyan)).clone(),
secondary_label: ColorSpec::new().set_fg(Some(blue)).clone(),
line_number: ColorSpec::new().set_fg(Some(blue)).clone(),
source_border: ColorSpec::new().set_fg(Some(blue)).clone(),
note_bullet: ColorSpec::new().set_fg(Some(blue)).clone(),
}
}
}
impl Default for Styles {
fn default() -> Styles {
// Blue is really difficult to see on the standard windows command line
#[cfg(windows)]
const BLUE: Color = Color::Cyan;
#[cfg(not(windows))]
const BLUE: Color = Color::Blue;
Self::with_blue(BLUE)
}
}
/// Characters to use when rendering the diagnostic.
///
/// By using [`Chars::ascii()`] you can switch to an ASCII-only format suitable
/// for rendering on terminals that do not support box drawing characters.
#[derive(Clone, Debug)]
pub struct Chars {
/// The characters to use for the top-left border of the snippet.
/// Defaults to: `"┌─"` or `"-->"` with [`Chars::ascii()`].
pub snippet_start: String,
/// The character to use for the left border of the source.
/// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`].
pub source_border_left: char,
/// The character to use for the left border break of the source.
/// Defaults to: `'·'` or `'.'` with [`Chars::ascii()`].
pub source_border_left_break: char,
/// The character to use for the note bullet.
/// Defaults to: `'='`.
pub note_bullet: char,
/// The character to use for marking a single-line primary label.
/// Defaults to: `'^'`.
pub single_primary_caret: char,
/// The character to use for marking a single-line secondary label.
/// Defaults to: `'-'`.
pub single_secondary_caret: char,
/// The character to use for marking the start of a multi-line primary label.
/// Defaults to: `'^'`.
pub multi_primary_caret_start: char,
/// The character to use for marking the end of a multi-line primary label.
/// Defaults to: `'^'`.
pub multi_primary_caret_end: char,
/// The character to use for marking the start of a multi-line secondary label.
/// Defaults to: `'\''`.
pub multi_secondary_caret_start: char,
/// The character to use for marking the end of a multi-line secondary label.
/// Defaults to: `'\''`.
pub multi_secondary_caret_end: char,
/// The character to use for the top-left corner of a multi-line label.
/// Defaults to: `'╭'` or `'/'` with [`Chars::ascii()`].
pub multi_top_left: char,
/// The character to use for the top of a multi-line label.
/// Defaults to: `'─'` or `'-'` with [`Chars::ascii()`].
pub multi_top: char,
/// The character to use for the bottom-left corner of a multi-line label.
/// Defaults to: `'╰'` or `'\'` with [`Chars::ascii()`].
pub multi_bottom_left: char,
/// The character to use when marking the bottom of a multi-line label.
/// Defaults to: `'─'` or `'-'` with [`Chars::ascii()`].
pub multi_bottom: char,
/// The character to use for the left of a multi-line label.
/// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`].
pub multi_left: char,
/// The character to use for the left of a pointer underneath a caret.
/// Defaults to: `'│'` or `'|'` with [`Chars::ascii()`].
pub pointer_left: char,
}
impl Default for Chars {
fn default() -> Chars {
Chars::box_drawing()
}
}
impl Chars {
/// A character set that uses Unicode box drawing characters.
pub fn box_drawing() -> Chars {
Chars {
snippet_start: "┌─".into(),
source_border_left: '',
source_border_left_break: '·',
note_bullet: '=',
single_primary_caret: '^',
single_secondary_caret: '-',
multi_primary_caret_start: '^',
multi_primary_caret_end: '^',
multi_secondary_caret_start: '\'',
multi_secondary_caret_end: '\'',
multi_top_left: '',
multi_top: '',
multi_bottom_left: '',
multi_bottom: '',
multi_left: '',
pointer_left: '',
}
}
/// A character set that only uses ASCII characters.
///
/// This is useful if your terminal's font does not support box drawing
/// characters well and results in output that looks similar to rustc's
/// diagnostic output.
pub fn ascii() -> Chars {
Chars {
snippet_start: "-->".into(),
source_border_left: '|',
source_border_left_break: '.',
note_bullet: '=',
single_primary_caret: '^',
single_secondary_caret: '-',
multi_primary_caret_start: '^',
multi_primary_caret_end: '^',
multi_secondary_caret_start: '\'',
multi_secondary_caret_end: '\'',
multi_top_left: '/',
multi_top: '-',
multi_bottom_left: '\\',
multi_bottom: '-',
multi_left: '|',
pointer_left: '|',
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,478 @@
use std::ops::Range;
use crate::diagnostic::{Diagnostic, LabelStyle};
use crate::files::{Error, Files, Location};
use crate::term::renderer::{Locus, MultiLabel, Renderer, SingleLabel};
use crate::term::Config;
/// Count the number of decimal digits in `n`.
fn count_digits(mut n: usize) -> usize {
let mut count = 0;
while n != 0 {
count += 1;
n /= 10; // remove last digit
}
count
}
/// Output a richly formatted diagnostic, with source code previews.
pub struct RichDiagnostic<'diagnostic, 'config, FileId> {
diagnostic: &'diagnostic Diagnostic<FileId>,
config: &'config Config,
}
impl<'diagnostic, 'config, FileId> RichDiagnostic<'diagnostic, 'config, FileId>
where
FileId: Copy + PartialEq,
{
pub fn new(
diagnostic: &'diagnostic Diagnostic<FileId>,
config: &'config Config,
) -> RichDiagnostic<'diagnostic, 'config, FileId> {
RichDiagnostic { diagnostic, config }
}
pub fn render<'files>(
&self,
files: &'files impl Files<'files, FileId = FileId>,
renderer: &mut Renderer<'_, '_>,
) -> Result<(), Error>
where
FileId: 'files,
{
use std::collections::BTreeMap;
struct LabeledFile<'diagnostic, FileId> {
file_id: FileId,
start: usize,
name: String,
location: Location,
num_multi_labels: usize,
lines: BTreeMap<usize, Line<'diagnostic>>,
max_label_style: LabelStyle,
}
impl<'diagnostic, FileId> LabeledFile<'diagnostic, FileId> {
fn get_or_insert_line(
&mut self,
line_index: usize,
line_range: Range<usize>,
line_number: usize,
) -> &mut Line<'diagnostic> {
self.lines.entry(line_index).or_insert_with(|| Line {
range: line_range,
number: line_number,
single_labels: vec![],
multi_labels: vec![],
// This has to be false by default so we know if it must be rendered by another condition already.
must_render: false,
})
}
}
struct Line<'diagnostic> {
number: usize,
range: std::ops::Range<usize>,
// TODO: How do we reuse these allocations?
single_labels: Vec<SingleLabel<'diagnostic>>,
multi_labels: Vec<(usize, LabelStyle, MultiLabel<'diagnostic>)>,
must_render: bool,
}
// TODO: Make this data structure external, to allow for allocation reuse
let mut labeled_files = Vec::<LabeledFile<'_, _>>::new();
// Keep track of the outer padding to use when rendering the
// snippets of source code.
let mut outer_padding = 0;
// Group labels by file
for label in &self.diagnostic.labels {
let start_line_index = files.line_index(label.file_id, label.range.start)?;
let start_line_number = files.line_number(label.file_id, start_line_index)?;
let start_line_range = files.line_range(label.file_id, start_line_index)?;
let end_line_index = files.line_index(label.file_id, label.range.end)?;
let end_line_number = files.line_number(label.file_id, end_line_index)?;
let end_line_range = files.line_range(label.file_id, end_line_index)?;
outer_padding = std::cmp::max(outer_padding, count_digits(start_line_number));
outer_padding = std::cmp::max(outer_padding, count_digits(end_line_number));
// NOTE: This could be made more efficient by using an associative
// data structure like a hashmap or B-tree, but we use a vector to
// preserve the order that unique files appear in the list of labels.
let labeled_file = match labeled_files
.iter_mut()
.find(|labeled_file| label.file_id == labeled_file.file_id)
{
Some(labeled_file) => {
// another diagnostic also referenced this file
if labeled_file.max_label_style > label.style
|| (labeled_file.max_label_style == label.style
&& labeled_file.start > label.range.start)
{
// this label has a higher style or has the same style but starts earlier
labeled_file.start = label.range.start;
labeled_file.location = files.location(label.file_id, label.range.start)?;
labeled_file.max_label_style = label.style;
}
labeled_file
}
None => {
// no other diagnostic referenced this file yet
labeled_files.push(LabeledFile {
file_id: label.file_id,
start: label.range.start,
name: files.name(label.file_id)?.to_string(),
location: files.location(label.file_id, label.range.start)?,
num_multi_labels: 0,
lines: BTreeMap::new(),
max_label_style: label.style,
});
// this unwrap should never fail because we just pushed an element
labeled_files
.last_mut()
.expect("just pushed an element that disappeared")
}
};
if start_line_index == end_line_index {
// Single line
//
// ```text
// 2 │ (+ test "")
// │ ^^ expected `Int` but found `String`
// ```
let label_start = label.range.start - start_line_range.start;
// Ensure that we print at least one caret, even when we
// have a zero-length source range.
let label_end =
usize::max(label.range.end - start_line_range.start, label_start + 1);
let line = labeled_file.get_or_insert_line(
start_line_index,
start_line_range,
start_line_number,
);
// Ensure that the single line labels are lexicographically
// sorted by the range of source code that they cover.
let index = match line.single_labels.binary_search_by(|(_, range, _)| {
// `Range<usize>` doesn't implement `Ord`, so convert to `(usize, usize)`
// to piggyback off its lexicographic comparison implementation.
(range.start, range.end).cmp(&(label_start, label_end))
}) {
// If the ranges are the same, order the labels in reverse
// to how they were originally specified in the diagnostic.
// This helps with printing in the renderer.
Ok(index) | Err(index) => index,
};
line.single_labels
.insert(index, (label.style, label_start..label_end, &label.message));
// If this line is not rendered, the SingleLabel is not visible.
line.must_render = true;
} else {
// Multiple lines
//
// ```text
// 4 │ fizz₁ num = case (mod num 5) (mod num 3) of
// │ ╭─────────────^
// 5 │ │ 0 0 => "FizzBuzz"
// 6 │ │ 0 _ => "Fizz"
// 7 │ │ _ 0 => "Buzz"
// 8 │ │ _ _ => num
// │ ╰──────────────^ `case` clauses have incompatible types
// ```
let label_index = labeled_file.num_multi_labels;
labeled_file.num_multi_labels += 1;
// First labeled line
let label_start = label.range.start - start_line_range.start;
let start_line = labeled_file.get_or_insert_line(
start_line_index,
start_line_range.clone(),
start_line_number,
);
start_line.multi_labels.push((
label_index,
label.style,
MultiLabel::Top(label_start),
));
// The first line has to be rendered so the start of the label is visible.
start_line.must_render = true;
// Marked lines
//
// ```text
// 5 │ │ 0 0 => "FizzBuzz"
// 6 │ │ 0 _ => "Fizz"
// 7 │ │ _ 0 => "Buzz"
// ```
for line_index in (start_line_index + 1)..end_line_index {
let line_range = files.line_range(label.file_id, line_index)?;
let line_number = files.line_number(label.file_id, line_index)?;
outer_padding = std::cmp::max(outer_padding, count_digits(line_number));
let line = labeled_file.get_or_insert_line(line_index, line_range, line_number);
line.multi_labels
.push((label_index, label.style, MultiLabel::Left));
// The line should be rendered to match the configuration of how much context to show.
line.must_render |=
// Is this line part of the context after the start of the label?
line_index - start_line_index <= self.config.start_context_lines
||
// Is this line part of the context before the end of the label?
end_line_index - line_index <= self.config.end_context_lines;
}
// Last labeled line
//
// ```text
// 8 │ │ _ _ => num
// │ ╰──────────────^ `case` clauses have incompatible types
// ```
let label_end = label.range.end - end_line_range.start;
let end_line = labeled_file.get_or_insert_line(
end_line_index,
end_line_range,
end_line_number,
);
end_line.multi_labels.push((
label_index,
label.style,
MultiLabel::Bottom(label_end, &label.message),
));
// The last line has to be rendered so the end of the label is visible.
end_line.must_render = true;
}
}
// Header and message
//
// ```text
// error[E0001]: unexpected type in `+` application
// ```
renderer.render_header(
None,
self.diagnostic.severity,
self.diagnostic.code.as_deref(),
self.diagnostic.message.as_str(),
)?;
// Source snippets
//
// ```text
// ┌─ test:2:9
// │
// 2 │ (+ test "")
// │ ^^ expected `Int` but found `String`
// │
// ```
let mut labeled_files = labeled_files.into_iter().peekable();
while let Some(labeled_file) = labeled_files.next() {
let source = files.source(labeled_file.file_id)?;
let source = source.as_ref();
// Top left border and locus.
//
// ```text
// ┌─ test:2:9
// ```
if !labeled_file.lines.is_empty() {
renderer.render_snippet_start(
outer_padding,
&Locus {
name: labeled_file.name,
location: labeled_file.location,
},
)?;
renderer.render_snippet_empty(
outer_padding,
self.diagnostic.severity,
labeled_file.num_multi_labels,
&[],
)?;
}
let mut lines = labeled_file
.lines
.iter()
.filter(|(_, line)| line.must_render)
.peekable();
while let Some((line_index, line)) = lines.next() {
renderer.render_snippet_source(
outer_padding,
line.number,
&source[line.range.clone()],
self.diagnostic.severity,
&line.single_labels,
labeled_file.num_multi_labels,
&line.multi_labels,
)?;
// Check to see if we need to render any intermediate stuff
// before rendering the next line.
if let Some((next_line_index, _)) = lines.peek() {
match next_line_index.checked_sub(*line_index) {
// Consecutive lines
Some(1) => {}
// One line between the current line and the next line
Some(2) => {
// Write a source line
let file_id = labeled_file.file_id;
// This line was not intended to be rendered initially.
// To render the line right, we have to get back the original labels.
let labels = labeled_file
.lines
.get(&(line_index + 1))
.map_or(&[][..], |line| &line.multi_labels[..]);
renderer.render_snippet_source(
outer_padding,
files.line_number(file_id, line_index + 1)?,
&source[files.line_range(file_id, line_index + 1)?],
self.diagnostic.severity,
&[],
labeled_file.num_multi_labels,
labels,
)?;
}
// More than one line between the current line and the next line.
Some(_) | None => {
// Source break
//
// ```text
// ·
// ```
renderer.render_snippet_break(
outer_padding,
self.diagnostic.severity,
labeled_file.num_multi_labels,
&line.multi_labels,
)?;
}
}
}
}
// Check to see if we should render a trailing border after the
// final line of the snippet.
if labeled_files.peek().is_none() && self.diagnostic.notes.is_empty() {
// We don't render a border if we are at the final newline
// without trailing notes, because it would end up looking too
// spaced-out in combination with the final new line.
} else {
// Render the trailing snippet border.
renderer.render_snippet_empty(
outer_padding,
self.diagnostic.severity,
labeled_file.num_multi_labels,
&[],
)?;
}
}
// Additional notes
//
// ```text
// = expected type `Int`
// found type `String`
// ```
for note in &self.diagnostic.notes {
renderer.render_snippet_note(outer_padding, note)?;
}
renderer.render_empty()
}
}
/// Output a short diagnostic, with a line number, severity, and message.
pub struct ShortDiagnostic<'diagnostic, FileId> {
diagnostic: &'diagnostic Diagnostic<FileId>,
show_notes: bool,
}
impl<'diagnostic, FileId> ShortDiagnostic<'diagnostic, FileId>
where
FileId: Copy + PartialEq,
{
pub fn new(
diagnostic: &'diagnostic Diagnostic<FileId>,
show_notes: bool,
) -> ShortDiagnostic<'diagnostic, FileId> {
ShortDiagnostic {
diagnostic,
show_notes,
}
}
pub fn render<'files>(
&self,
files: &'files impl Files<'files, FileId = FileId>,
renderer: &mut Renderer<'_, '_>,
) -> Result<(), Error>
where
FileId: 'files,
{
// Located headers
//
// ```text
// test:2:9: error[E0001]: unexpected type in `+` application
// ```
let mut primary_labels_encountered = 0;
let labels = self.diagnostic.labels.iter();
for label in labels.filter(|label| label.style == LabelStyle::Primary) {
primary_labels_encountered += 1;
renderer.render_header(
Some(&Locus {
name: files.name(label.file_id)?.to_string(),
location: files.location(label.file_id, label.range.start)?,
}),
self.diagnostic.severity,
self.diagnostic.code.as_deref(),
self.diagnostic.message.as_str(),
)?;
}
// Fallback to printing a non-located header if no primary labels were encountered
//
// ```text
// error[E0002]: Bad config found
// ```
if primary_labels_encountered == 0 {
renderer.render_header(
None,
self.diagnostic.severity,
self.diagnostic.code.as_deref(),
self.diagnostic.message.as_str(),
)?;
}
if self.show_notes {
// Additional notes
//
// ```text
// = expected type `Int`
// found type `String`
// ```
for note in &self.diagnostic.notes {
renderer.render_snippet_note(0, note)?;
}
}
Ok(())
}
}

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}bug{bold bright}: {/}
{fg:Red bold bright}error{bold bright}: {/}
{fg:Yellow bold bright}warning{bold bright}: {/}
{fg:Green bold bright}note{bold bright}: {/}
{fg:Cyan bold bright}help{bold bright}: {/}
{fg:Red bold bright}bug{bold bright}: {/}

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
bug:
error:
warning:
note:
help:
bug:

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
bug:
error:
warning:
note:
help:
bug:

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}bug{bold bright}: {/}
{fg:Red bold bright}error{bold bright}: {/}
{fg:Yellow bold bright}warning{bold bright}: {/}
{fg:Green bold bright}note{bold bright}: {/}
{fg:Cyan bold bright}help{bold bright}: {/}
{fg:Red bold bright}bug{bold bright}: {/}

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
bug:
error:
warning:
note:
help:
bug:

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}bug{bold bright}: {/}
{fg:Red bold bright}error{bold bright}: {/}
{fg:Yellow bold bright}warning{bold bright}: {/}
{fg:Green bold bright}note{bold bright}: {/}
{fg:Cyan bold bright}help{bold bright}: {/}
{fg:Red bold bright}bug{bold bright}: {/}

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
bug:
error:
warning:
note:
help:
bug:

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
hello:1:7: {fg:Green bold bright}note{bold bright}: middle{/}
hello:1:13: {fg:Green bold bright}note{bold bright}: end of line{/}
hello:2:11: {fg:Green bold bright}note{bold bright}: end of line{/}
hello:3:4: {fg:Green bold bright}note{bold bright}: end of file{/}

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
hello:1:7: note: middle
hello:1:13: note: end of line
hello:2:11: note: end of line
hello:3:4: note: end of file

View File

@@ -0,0 +1,29 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
note: middle
--> hello:1:7
|
1 | Hello world!
| ^ middle
note: end of line
--> hello:1:13
|
1 | Hello world!
| ^ end of line
note: end of line
--> hello:2:11
|
2 | Bye world!
| ^ end of line
note: end of file
--> hello:3:4
|
3 |
| ^ end of file

View File

@@ -0,0 +1,29 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Green bold bright}note{bold bright}: middle{/}
{fg:Blue}┌─{/} hello:1:7
{fg:Blue}│{/}
{fg:Blue}1{/} {fg:Blue}│{/} Hello {fg:Green}w{/}orld!
{fg:Blue}│{/} {fg:Green}^{/} {fg:Green}middle{/}
{fg:Green bold bright}note{bold bright}: end of line{/}
{fg:Blue}┌─{/} hello:1:13
{fg:Blue}│{/}
{fg:Blue}1{/} {fg:Blue}│{/} Hello world!
{fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of line{/}
{fg:Green bold bright}note{bold bright}: end of line{/}
{fg:Blue}┌─{/} hello:2:11
{fg:Blue}│{/}
{fg:Blue}2{/} {fg:Blue}│{/} Bye world!
{fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of line{/}
{fg:Green bold bright}note{bold bright}: end of file{/}
{fg:Blue}┌─{/} hello:3:4
{fg:Blue}│{/}
{fg:Blue}3{/} {fg:Blue}│{/}
{fg:Blue}│{/} {fg:Green}^{/} {fg:Green}end of file{/}

View File

@@ -0,0 +1,29 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
note: middle
┌─ hello:1:7
1 │ Hello world!
│ ^ middle
note: end of line
┌─ hello:1:13
1 │ Hello world!
│ ^ end of line
note: end of line
┌─ hello:2:11
2 │ Bye world!
│ ^ end of line
note: end of file
┌─ hello:3:4
3 │
│ ^ end of file

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
hello:1:7: {fg:Green bold bright}note{bold bright}: middle{/}
hello:1:13: {fg:Green bold bright}note{bold bright}: end of line{/}
hello:2:11: {fg:Green bold bright}note{bold bright}: end of line{/}
hello:3:4: {fg:Green bold bright}note{bold bright}: end of file{/}

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
hello:1:7: note: middle
hello:1:13: note: end of line
hello:2:11: note: end of line
hello:3:4: note: end of file

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
FizzBuzz.fun:8:12: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}
{fg:Blue}={/} expected type `String`
found type `Nat`
FizzBuzz.fun:16:16: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}
{fg:Blue}={/} expected type `String`
found type `Nat`

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
FizzBuzz.fun:8:12: error[E0308]: `case` clauses have incompatible types
= expected type `String`
found type `Nat`
FizzBuzz.fun:16:16: error[E0308]: `case` clauses have incompatible types
= expected type `String`
found type `Nat`

View File

@@ -0,0 +1,42 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0308]: `case` clauses have incompatible types
--> FizzBuzz.fun:8:12
|
3 | fizz₁ : Nat → String
| ------ expected type `String` found here
4 | fizz₁ num = case (mod num 5) (mod num 3) of
| /-------------'
5 | | 0 0 => "FizzBuzz"
6 | | 0 _ => "Fizz"
7 | | _ 0 => "Buzz"
8 | | _ _ => num
| | ^^^ expected `String`, found `Nat`
| \--------------' `case` clauses have incompatible types
|
= expected type `String`
found type `Nat`
error[E0308]: `case` clauses have incompatible types
--> FizzBuzz.fun:16:16
|
10 | fizz₂ : Nat → String
| ------ expected type `String` found here
11 | fizz₂ num =
12 | / case (mod num 5) (mod num 3) of
13 | | 0 0 => "FizzBuzz"
| | ---------- this is found to be of type `String`
14 | | 0 _ => "Fizz"
| | ------ this is found to be of type `String`
15 | | _ 0 => "Buzz"
| | ------ this is found to be of type `String`
16 | | _ _ => num
| | ^^^ expected `String`, found `Nat`
| \------------------' `case` clauses have incompatible types
|
= expected type `String`
found type `Nat`

View File

@@ -0,0 +1,42 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}
{fg:Blue}┌─{/} FizzBuzz.fun:8:12
{fg:Blue}│{/}
{fg:Blue}3{/} {fg:Blue}│{/} fizz₁ : Nat → String
{fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}expected type `String` found here{/}
{fg:Blue}4{/} {fg:Blue}│{/} fizz₁ num = case (mod num 5) (mod num 3) of
{fg:Blue}│{/} {fg:Blue}╭{/}{fg:Blue}─────────────'{/}
{fg:Blue}5{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 0 => "FizzBuzz"
{fg:Blue}6{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 _ => "Fizz"
{fg:Blue}7{/} {fg:Blue}│{/} {fg:Blue}│{/} _ 0 => "Buzz"
{fg:Blue}8{/} {fg:Blue}│{/} {fg:Blue}│{/} _ _ => {fg:Red}num{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}^^^{/} {fg:Red}expected `String`, found `Nat`{/}
{fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────────────' `case` clauses have incompatible types{/}
{fg:Blue}│{/}
{fg:Blue}={/} expected type `String`
found type `Nat`
{fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}
{fg:Blue}┌─{/} FizzBuzz.fun:16:16
{fg:Blue}│{/}
{fg:Blue}10{/} {fg:Blue}│{/} fizz₂ : Nat → String
{fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}expected type `String` found here{/}
{fg:Blue}11{/} {fg:Blue}│{/} fizz₂ num =
{fg:Blue}12{/} {fg:Blue}│{/} {fg:Blue}╭{/} case (mod num 5) (mod num 3) of
{fg:Blue}13{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 0 => "FizzBuzz"
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}----------{/} {fg:Blue}this is found to be of type `String`{/}
{fg:Blue}14{/} {fg:Blue}│{/} {fg:Blue}│{/} 0 _ => "Fizz"
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}this is found to be of type `String`{/}
{fg:Blue}15{/} {fg:Blue}│{/} {fg:Blue}│{/} _ 0 => "Buzz"
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}------{/} {fg:Blue}this is found to be of type `String`{/}
{fg:Blue}16{/} {fg:Blue}│{/} {fg:Blue}│{/} _ _ => {fg:Red}num{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}^^^{/} {fg:Red}expected `String`, found `Nat`{/}
{fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────────────────' `case` clauses have incompatible types{/}
{fg:Blue}│{/}
{fg:Blue}={/} expected type `String`
found type `Nat`

View File

@@ -0,0 +1,42 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0308]: `case` clauses have incompatible types
┌─ FizzBuzz.fun:8:12
3 │ fizz₁ : Nat → String
│ ------ expected type `String` found here
4 │ fizz₁ num = case (mod num 5) (mod num 3) of
│ ╭─────────────'
5 │ │ 0 0 => "FizzBuzz"
6 │ │ 0 _ => "Fizz"
7 │ │ _ 0 => "Buzz"
8 │ │ _ _ => num
│ │ ^^^ expected `String`, found `Nat`
│ ╰──────────────' `case` clauses have incompatible types
= expected type `String`
found type `Nat`
error[E0308]: `case` clauses have incompatible types
┌─ FizzBuzz.fun:16:16
10 │ fizz₂ : Nat → String
│ ------ expected type `String` found here
11 │ fizz₂ num =
12 │ ╭ case (mod num 5) (mod num 3) of
13 │ │ 0 0 => "FizzBuzz"
│ │ ---------- this is found to be of type `String`
14 │ │ 0 _ => "Fizz"
│ │ ------ this is found to be of type `String`
15 │ │ _ 0 => "Buzz"
│ │ ------ this is found to be of type `String`
16 │ │ _ _ => num
│ │ ^^^ expected `String`, found `Nat`
│ ╰──────────────────' `case` clauses have incompatible types
= expected type `String`
found type `Nat`

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
FizzBuzz.fun:8:12: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}
FizzBuzz.fun:16:16: {fg:Red bold bright}error[E0308]{bold bright}: `case` clauses have incompatible types{/}

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
FizzBuzz.fun:8:12: error[E0308]: `case` clauses have incompatible types
FizzBuzz.fun:16:16: error[E0308]: `case` clauses have incompatible types

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Cyan bold bright}help{bold bright}: a message{/}

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
warning: a message
note: a message
help: a message

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
warning: a message
note: a message
help: a message

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Cyan bold bright}help{bold bright}: a message{/}

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
warning: a message
note: a message
help: a message

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Cyan bold bright}help{bold bright}: a message{/}

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
warning: a message
note: a message
help: a message

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Cyan bold bright}help{bold bright}: a message{/}
{fg:Blue}={/} a note

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
= a note
warning: a message
= a note
note: a message
= a note
help: a message
= a note

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
= a note
warning: a message
= a note
note: a message
= a note
help: a message
= a note

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Blue}={/} a note
{fg:Cyan bold bright}help{bold bright}: a message{/}
{fg:Blue}={/} a note

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
= a note
warning: a message
= a note
note: a message
= a note
help: a message
= a note

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: a message{/}
{fg:Yellow bold bright}warning{bold bright}: a message{/}
{fg:Green bold bright}note{bold bright}: a message{/}
{fg:Cyan bold bright}help{bold bright}: a message{/}

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: a message
warning: a message
note: a message
help: a message

View File

@@ -0,0 +1,21 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0001]: a message
warning[W001]: a message
note[N0815]: a message
help[H4711]: a message
error: where did my errorcode go?
warning: where did my errorcode go?
note: where did my errorcode go?
help: where did my errorcode go?

View File

@@ -0,0 +1,21 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0001]: a message
warning[W001]: a message
note[N0815]: a message
help[H4711]: a message
error: where did my errorcode go?
warning: where did my errorcode go?
note: where did my errorcode go?
help: where did my errorcode go?

View File

@@ -0,0 +1,13 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0001]: a message
warning[W001]: a message
note[N0815]: a message
help[H4711]: a message
error: where did my errorcode go?
warning: where did my errorcode go?
note: where did my errorcode go?
help: where did my errorcode go?

View File

@@ -0,0 +1,12 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
Data/Nat.fun:7:13: {fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/}
{fg:Blue}={/} there is a builtin with a similar name: `NATURAL`
Data/Nat.fun:17:16: {fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/}
{fg:Blue}={/} consider using a wildcard pattern: `_`
Test.fun:4:11: {fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/}
{fg:Blue}={/} expected type `Nat`
found type `String`

View File

@@ -0,0 +1,12 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
Data/Nat.fun:7:13: error: unknown builtin: `NATRAL`
= there is a builtin with a similar name: `NATURAL`
Data/Nat.fun:17:16: warning: unused parameter pattern: `n₂`
= consider using a wildcard pattern: `_`
Test.fun:4:11: error[E0001]: unexpected type in application of `_+_`
= expected type `Nat`
found type `String`

View File

@@ -0,0 +1,35 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: unknown builtin: `NATRAL`
--> Data/Nat.fun:7:13
|
7 | {-# BUILTIN NATRAL Nat #-}
| ^^^^^^ unknown builtin
|
= there is a builtin with a similar name: `NATURAL`
warning: unused parameter pattern: `n₂`
--> Data/Nat.fun:17:16
|
17 | zero - succ n₂ = zero
| ^^ unused parameter
|
= consider using a wildcard pattern: `_`
error[E0001]: unexpected type in application of `_+_`
--> Test.fun:4:11
|
4 | _ = 123 + "hello"
| ^^^^^^^ expected `Nat`, found `String`
|
--> Data/Nat.fun:11:1
|
11 | _+_ : Nat → Nat → Nat
| --------------------- based on the definition of `_+_`
|
= expected type `Nat`
found type `String`

View File

@@ -0,0 +1,35 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/}
{fg:Blue}┌─{/} Data/Nat.fun:7:13
{fg:Blue}│{/}
{fg:Blue}7{/} {fg:Blue}│{/} {-# BUILTIN {fg:Red}NATRAL{/} Nat #-}
{fg:Blue}│{/} {fg:Red}^^^^^^{/} {fg:Red}unknown builtin{/}
{fg:Blue}│{/}
{fg:Blue}={/} there is a builtin with a similar name: `NATURAL`
{fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/}
{fg:Blue}┌─{/} Data/Nat.fun:17:16
{fg:Blue}│{/}
{fg:Blue}17{/} {fg:Blue}│{/} zero - succ {fg:Yellow}n₂{/} = zero
{fg:Blue}│{/} {fg:Yellow}^^{/} {fg:Yellow}unused parameter{/}
{fg:Blue}│{/}
{fg:Blue}={/} consider using a wildcard pattern: `_`
{fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/}
{fg:Blue}┌─{/} Test.fun:4:11
{fg:Blue}│{/}
{fg:Blue} 4{/} {fg:Blue}│{/} _ = 123 + {fg:Red}"hello"{/}
{fg:Blue}│{/} {fg:Red}^^^^^^^{/} {fg:Red}expected `Nat`, found `String`{/}
{fg:Blue}│{/}
{fg:Blue}┌─{/} Data/Nat.fun:11:1
{fg:Blue}│{/}
{fg:Blue}11{/} {fg:Blue}│{/} _+_ : Nat → Nat → Nat
{fg:Blue}│{/} {fg:Blue}---------------------{/} {fg:Blue}based on the definition of `_+_`{/}
{fg:Blue}│{/}
{fg:Blue}={/} expected type `Nat`
found type `String`

View File

@@ -0,0 +1,35 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: unknown builtin: `NATRAL`
┌─ Data/Nat.fun:7:13
7 │ {-# BUILTIN NATRAL Nat #-}
│ ^^^^^^ unknown builtin
= there is a builtin with a similar name: `NATURAL`
warning: unused parameter pattern: `n₂`
┌─ Data/Nat.fun:17:16
17 │ zero - succ n₂ = zero
│ ^^ unused parameter
= consider using a wildcard pattern: `_`
error[E0001]: unexpected type in application of `_+_`
┌─ Test.fun:4:11
4 │ _ = 123 + "hello"
│ ^^^^^^^ expected `Nat`, found `String`
┌─ Data/Nat.fun:11:1
11 │ _+_ : Nat → Nat → Nat
│ --------------------- based on the definition of `_+_`
= expected type `Nat`
found type `String`

View File

@@ -0,0 +1,8 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
Data/Nat.fun:7:13: {fg:Red bold bright}error{bold bright}: unknown builtin: `NATRAL`{/}
Data/Nat.fun:17:16: {fg:Yellow bold bright}warning{bold bright}: unused parameter pattern: `n₂`{/}
Test.fun:4:11: {fg:Red bold bright}error[E0001]{bold bright}: unexpected type in application of `_+_`{/}

View File

@@ -0,0 +1,8 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
Data/Nat.fun:7:13: error: unknown builtin: `NATRAL`
Data/Nat.fun:17:16: warning: unused parameter pattern: `n₂`
Test.fun:4:11: error[E0001]: unexpected type in application of `_+_`

View File

@@ -0,0 +1,38 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[empty_if]: empty elseif block
┌─ empty_if_comments.lua:1:1
1 │ ╭ elseif 3 then
2 │ │
3 │ │ ╭
4 │ │ │
5 │ │ │
· │ │
8 │ │ │
9 │ │ │
│ │ ╰' content should be in here
10 │ │ else
│ ╰───^
error[E0308]: mismatched types
┌─ src/lib.rs:2:6
2 │ 1
│ ╭─────^
3 │ │ + 1
4 │ │ + 1
· │
7 │ │ +1
│ │ - missing whitespace
8 │ │ + 1
9 │ │ + 1
10 │ │ + 1
│ ╰───────^ expected (), found integer
= note: expected type `()`
found type `{integer}`

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
codespan/src/file.rs:4:34: {fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/}
{fg:Blue}={/} expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`

View File

@@ -0,0 +1,9 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
codespan/src/file.rs:4:34: error[E0308]: match arms have incompatible types
= expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`

View File

@@ -0,0 +1,25 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0308]: match arms have incompatible types
--> codespan/src/file.rs:4:34
|
1 | / match line_index.compare(self.last_line_index()) {
2 | | Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
| | --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
3 | | Ordering::Equal => Ok(self.source_span().end()),
| | ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
4 | | Ordering::Greater => LineIndexOutOfBoundsError {
| /-|----------------------------------^
5 | | | given: line_index,
6 | | | max: self.last_line_index(),
7 | | | },
| \-|-------------^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
8 | | }
| \---------' `match` arms have incompatible types
|
= expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`

View File

@@ -0,0 +1,25 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/}
{fg:Blue}┌─{/} codespan/src/file.rs:4:34
{fg:Blue}│{/}
{fg:Blue}1{/} {fg:Blue}│{/} {fg:Blue}╭{/} match line_index.compare(self.last_line_index()) {
{fg:Blue}2{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}---------------------------------------------{/} {fg:Blue}this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`{/}
{fg:Blue}3{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Equal => Ok(self.source_span().end()),
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}----------------------------{/} {fg:Blue}this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`{/}
{fg:Blue}4{/} {fg:Blue}│{/} {fg:Blue}│{/} Ordering::Greater => {fg:Red}LineIndexOutOfBoundsError {{/}
{fg:Blue}│{/} {fg:Red}╭{/}{fg:Red}─{/}{fg:Blue}│{/}{fg:Red}──────────────────────────────────^{/}
{fg:Blue}5{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} given: line_index,{/}
{fg:Blue}6{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} max: self.last_line_index(),{/}
{fg:Blue}7{/} {fg:Blue}│{/} {fg:Red}│{/} {fg:Blue}│{/} {fg:Red} }{/},
{fg:Blue}│{/} {fg:Red}╰{/}{fg:Red}─{/}{fg:Blue}│{/}{fg:Red}─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`{/}
{fg:Blue}8{/} {fg:Blue}│{/} {fg:Blue}│{/} }
{fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}─────────' `match` arms have incompatible types{/}
{fg:Blue}│{/}
{fg:Blue}={/} expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`

View File

@@ -0,0 +1,25 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0308]: match arms have incompatible types
┌─ codespan/src/file.rs:4:34
1 │ ╭ match line_index.compare(self.last_line_index()) {
2 │ │ Ordering::Less => Ok(self.line_starts()[line_index.to_usize()]),
│ │ --------------------------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
3 │ │ Ordering::Equal => Ok(self.source_span().end()),
│ │ ---------------------------- this is found to be of type `Result<ByteIndex, LineIndexOutOfBoundsError>`
4 │ │ Ordering::Greater => LineIndexOutOfBoundsError {
│ ╭─│──────────────────────────────────^
5 │ │ │ given: line_index,
6 │ │ │ max: self.last_line_index(),
7 │ │ │ },
│ ╰─│─────────────^ expected enum `Result`, found struct `LineIndexOutOfBoundsError`
8 │ │ }
│ ╰─────────' `match` arms have incompatible types
= expected type `Result<ByteIndex, LineIndexOutOfBoundsError>`
found type `LineIndexOutOfBoundsError`

View File

@@ -0,0 +1,6 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
codespan/src/file.rs:4:34: {fg:Red bold bright}error[E0308]{bold bright}: match arms have incompatible types{/}

View File

@@ -0,0 +1,6 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
codespan/src/file.rs:4:34: error[E0308]: match arms have incompatible types

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
nested_impl_trait.rs:5:56: {fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/}
typeck_type_placeholder_item.rs:1:18: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
typeck_type_placeholder_item.rs:2:25: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
typeck_type_placeholder_item.rs:2:28: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
no_send_res_ports.rs:25:5: {fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/}
{fg:Blue}={/} help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
{fg:Blue}={/} note: required because it appears within the type `Port<()>`
{fg:Blue}={/} note: required because it appears within the type `main::Foo`
{fg:Blue}={/} note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
{fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/}
{fg:Blue}={/} Some errors have detailed explanations: E0121, E0277, E0666.
{fg:Blue}={/} For more information about an error, try `rustc --explain E0121`.

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
nested_impl_trait.rs:5:56: error[E0666]: nested `impl Trait` is not allowed
typeck_type_placeholder_item.rs:1:18: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
typeck_type_placeholder_item.rs:2:25: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
typeck_type_placeholder_item.rs:2:28: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
no_send_res_ports.rs:25:5: error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
= help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
= note: required because it appears within the type `Port<()>`
= note: required because it appears within the type `main::Foo`
= note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
error: aborting due 5 previous errors
= Some errors have detailed explanations: E0121, E0277, E0666.
= For more information about an error, try `rustc --explain E0121`.

View File

@@ -0,0 +1,58 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0666]: nested `impl Trait` is not allowed
--> nested_impl_trait.rs:5:56
|
5 | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
| | |
| | nested `impl Trait` here
| outer `impl Trait`
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> typeck_type_placeholder_item.rs:1:18
|
1 | fn fn_test1() -> _ { 5 }
| ^
| |
| not allowed in type signatures
| help: replace with the correct return type: `i32`
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> typeck_type_placeholder_item.rs:2:25
|
2 | fn fn_test2(x: i32) -> (_, _) { (x, x) }
| -^--^-
| || |
| || not allowed in type signatures
| |not allowed in type signatures
| help: replace with the correct return type: `(i32, i32)`
error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
--> no_send_res_ports.rs:25:5
|
25 | thread::spawn(move|| {
| ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
| /-------------------'
26 | | let y = x;
27 | | println!("{:?}", y);
28 | | });
| \------' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
|
--> libstd/thread/mod.rs:5:8
|
5 | F: Send + 'static,
| ---- required by this bound in `std::thread::spawn`
|
= help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
= note: required because it appears within the type `Port<()>`
= note: required because it appears within the type `main::Foo`
= note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
error: aborting due 5 previous errors
= Some errors have detailed explanations: E0121, E0277, E0666.
= For more information about an error, try `rustc --explain E0121`.

View File

@@ -0,0 +1,58 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/}
{fg:Blue}┌─{/} nested_impl_trait.rs:5:56
{fg:Blue}│{/}
{fg:Blue}5{/} {fg:Blue}│{/} fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<{fg:Red}impl Debug{/}> { x }
{fg:Blue}│{/} {fg:Blue}----------{fg:Red}^^^^^^^^^^{fg:Blue}-{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}│{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Red}nested `impl Trait` here{/}
{fg:Blue}│{/} {fg:Blue}outer `impl Trait`{/}
{fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
{fg:Blue}┌─{/} typeck_type_placeholder_item.rs:1:18
{fg:Blue}│{/}
{fg:Blue}1{/} {fg:Blue}│{/} fn fn_test1() -> {fg:Red}_{/} { 5 }
{fg:Blue}│{/} {fg:Red}^{/}
{fg:Blue}│{/} {fg:Red}│{/}
{fg:Blue}│{/} {fg:Red}not allowed in type signatures{/}
{fg:Blue}│{/} {fg:Blue}help: replace with the correct return type: `i32`{/}
{fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
{fg:Blue}┌─{/} typeck_type_placeholder_item.rs:2:25
{fg:Blue}│{/}
{fg:Blue}2{/} {fg:Blue}│{/} fn fn_test2(x: i32) -> ({fg:Red}_{/}, {fg:Red}_{/}) { (x, x) }
{fg:Blue}│{/} {fg:Blue}-{fg:Red}^{fg:Blue}--{fg:Red}^{fg:Blue}-{/}
{fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}│{/} {fg:Red}│{/}
{fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}│{/} {fg:Red}not allowed in type signatures{/}
{fg:Blue}│{/} {fg:Blue}│{/}{fg:Red}not allowed in type signatures{/}
{fg:Blue}│{/} {fg:Blue}help: replace with the correct return type: `(i32, i32)`{/}
{fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/}
{fg:Blue}┌─{/} no_send_res_ports.rs:25:5
{fg:Blue}│{/}
{fg:Blue}25{/} {fg:Blue}│{/} {fg:Red}thread::spawn{/}(move|| {
{fg:Blue}│{/} {fg:Red}^^^^^^^^^^^^^{/} {fg:Red}`std::rc::Rc<()>` cannot be sent between threads safely{/}
{fg:Blue}│{/} {fg:Blue}╭{/}{fg:Blue}───────────────────'{/}
{fg:Blue}26{/} {fg:Blue}│{/} {fg:Blue}│{/} let y = x;
{fg:Blue}27{/} {fg:Blue}│{/} {fg:Blue}│{/} println!("{:?}", y);
{fg:Blue}28{/} {fg:Blue}│{/} {fg:Blue}│{/} });
{fg:Blue}│{/} {fg:Blue}╰{/}{fg:Blue}──────' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`{/}
{fg:Blue}│{/}
{fg:Blue}┌─{/} libstd/thread/mod.rs:5:8
{fg:Blue}│{/}
{fg:Blue} 5{/} {fg:Blue}│{/} F: Send + 'static,
{fg:Blue}│{/} {fg:Blue}----{/} {fg:Blue}required by this bound in `std::thread::spawn`{/}
{fg:Blue}│{/}
{fg:Blue}={/} help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
{fg:Blue}={/} note: required because it appears within the type `Port<()>`
{fg:Blue}={/} note: required because it appears within the type `main::Foo`
{fg:Blue}={/} note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
{fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/}
{fg:Blue}={/} Some errors have detailed explanations: E0121, E0277, E0666.
{fg:Blue}={/} For more information about an error, try `rustc --explain E0121`.

View File

@@ -0,0 +1,58 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0666]: nested `impl Trait` is not allowed
┌─ nested_impl_trait.rs:5:56
5 │ fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
│ ----------^^^^^^^^^^-
│ │ │
│ │ nested `impl Trait` here
│ outer `impl Trait`
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
┌─ typeck_type_placeholder_item.rs:1:18
1 │ fn fn_test1() -> _ { 5 }
│ ^
│ │
│ not allowed in type signatures
│ help: replace with the correct return type: `i32`
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
┌─ typeck_type_placeholder_item.rs:2:25
2 │ fn fn_test2(x: i32) -> (_, _) { (x, x) }
│ -^--^-
│ ││ │
│ ││ not allowed in type signatures
│ │not allowed in type signatures
│ help: replace with the correct return type: `(i32, i32)`
error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
┌─ no_send_res_ports.rs:25:5
25 │ thread::spawn(move|| {
│ ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
│ ╭───────────────────'
26 │ │ let y = x;
27 │ │ println!("{:?}", y);
28 │ │ });
│ ╰──────' within this `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
┌─ libstd/thread/mod.rs:5:8
5 │ F: Send + 'static,
│ ---- required by this bound in `std::thread::spawn`
= help: within `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
= note: required because it appears within the type `Port<()>`
= note: required because it appears within the type `main::Foo`
= note: required because it appears within the type `[closure@no_send_res_ports.rs:29:19: 33:6 x:main::Foo]`
error: aborting due 5 previous errors
= Some errors have detailed explanations: E0121, E0277, E0666.
= For more information about an error, try `rustc --explain E0121`.

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
nested_impl_trait.rs:5:56: {fg:Red bold bright}error[E0666]{bold bright}: nested `impl Trait` is not allowed{/}
typeck_type_placeholder_item.rs:1:18: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
typeck_type_placeholder_item.rs:2:25: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
typeck_type_placeholder_item.rs:2:28: {fg:Red bold bright}error[E0121]{bold bright}: the type placeholder `_` is not allowed within types on item signatures{/}
no_send_res_ports.rs:25:5: {fg:Red bold bright}error[E0277]{bold bright}: `std::rc::Rc<()>` cannot be sent between threads safely{/}
{fg:Red bold bright}error{bold bright}: aborting due 5 previous errors{/}

View File

@@ -0,0 +1,11 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
nested_impl_trait.rs:5:56: error[E0666]: nested `impl Trait` is not allowed
typeck_type_placeholder_item.rs:1:18: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
typeck_type_placeholder_item.rs:2:25: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
typeck_type_placeholder_item.rs:2:28: error[E0121]: the type placeholder `_` is not allowed within types on item signatures
no_send_res_ports.rs:25:5: error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
error: aborting due 5 previous errors

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
tests/main.js:4:3: warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode

View File

@@ -0,0 +1,14 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode
--> tests/main.js:4:3
|
1 | "use strict";
| ------------ Strict mode is first declared here
.
4 | "use strict";
| ^^^^^^^^^^^^ This strict mode declaration is redundant

View File

@@ -0,0 +1,14 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode
┌─ tests/main.js:4:3
1 │ "use strict";
│ ------------ Strict mode is first declared here
·
4 │ "use strict";
│ ^^^^^^^^^^^^ This strict mode declaration is redundant

View File

@@ -0,0 +1,6 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
tests/main.js:4:3: warning[ParserWarning]: The strict mode declaration in the body of function `foo` is redundant, as the outer scope is already in strict mode

View File

@@ -0,0 +1,8 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
one_line.rs:3:12: {fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/}
{fg:Red bold bright}error{bold bright}: aborting due to previous error{/}
{fg:Blue}={/} For more information about this error, try `rustc --explain E0499`.

View File

@@ -0,0 +1,8 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
one_line.rs:3:12: error[E0499]: cannot borrow `v` as mutable more than once at a time
error: aborting due to previous error
= For more information about this error, try `rustc --explain E0499`.

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0499]: cannot borrow `v` as mutable more than once at a time
--> one_line.rs:3:12
|
3 | v.push(v.pop().unwrap());
| - ---- ^ second mutable borrow occurs here
| | |
| | first mutable borrow occurs here
| first borrow later used by call
error: aborting due to previous error
= For more information about this error, try `rustc --explain E0499`.

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/}
{fg:Blue}┌─{/} one_line.rs:3:12
{fg:Blue}│{/}
{fg:Blue}3{/} {fg:Blue}│{/} v.push({fg:Red}v{/}.pop().unwrap());
{fg:Blue}│{/} {fg:Blue}-{/} {fg:Blue}----{/} {fg:Red}^{/} {fg:Red}second mutable borrow occurs here{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}│{/}
{fg:Blue}│{/} {fg:Blue}│{/} {fg:Blue}first mutable borrow occurs here{/}
{fg:Blue}│{/} {fg:Blue}first borrow later used by call{/}
{fg:Red bold bright}error{bold bright}: aborting due to previous error{/}
{fg:Blue}={/} For more information about this error, try `rustc --explain E0499`.

View File

@@ -0,0 +1,17 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error[E0499]: cannot borrow `v` as mutable more than once at a time
┌─ one_line.rs:3:12
3 │ v.push(v.pop().unwrap());
│ - ---- ^ second mutable borrow occurs here
│ │ │
│ │ first mutable borrow occurs here
│ first borrow later used by call
error: aborting due to previous error
= For more information about this error, try `rustc --explain E0499`.

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
one_line.rs:3:12: {fg:Red bold bright}error[E0499]{bold bright}: cannot borrow `v` as mutable more than once at a time{/}
{fg:Red bold bright}error{bold bright}: aborting due to previous error{/}

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
one_line.rs:3:12: error[E0499]: cannot borrow `v` as mutable more than once at a time
error: aborting due to previous error

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
same_range:1:5: {fg:Red bold bright}error{bold bright}: Unexpected token{/}

View File

@@ -0,0 +1,7 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
same_range:1:5: error: Unexpected token

View File

@@ -0,0 +1,14 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: Unexpected token
--> same_range:1:5
|
1 | ::S { }
| ^
| |
| Unexpected '{'
| Expected '('

View File

@@ -0,0 +1,14 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
{fg:Red bold bright}error{bold bright}: Unexpected token{/}
{fg:Blue}┌─{/} same_range:1:5
{fg:Blue}│{/}
{fg:Blue}1{/} {fg:Blue}│{/} ::S {fg:Red}{{/} }
{fg:Blue}│{/} {fg:Red}^{/}
{fg:Blue}│{/} {fg:Red}│{/}
{fg:Blue}│{/} {fg:Red}Unexpected '{'{/}
{fg:Blue}│{/} {fg:Blue}Expected '('{/}

View File

@@ -0,0 +1,14 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
error: Unexpected token
┌─ same_range:1:5
1 │ ::S { }
│ ^
│ │
│ Unexpected '{'
│ Expected '('

View File

@@ -0,0 +1,6 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_color(&config)
---
same_range:1:5: {fg:Red bold bright}error{bold bright}: Unexpected token{/}

View File

@@ -0,0 +1,6 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
same_range:1:5: error: Unexpected token

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: tab test
┌─ tab_columns:1:2
1 │ hello
│ ^^^^^
2 │ ∙ hello
│ ^^^^^
3 │ ∙∙ hello
│ ^^^^^
4 │ ∙∙∙ hello
│ ^^^^^
5 │ ∙∙∙∙ hello
│ ^^^^^
6 │ ∙∙∙∙∙ hello
│ ^^^^^
7 │ ∙∙∙∙∙∙ hello
│ ^^^^^

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: unknown weapon `DogJaw`
┌─ tabbed:3:11
3 │ Weapon: DogJaw
│ ^^^^^^ the weapon
warning: unknown condition `attack-cooldown`
┌─ tabbed:4:23
4 │ ReloadingCondition: attack-cooldown
│ ^^^^^^^^^^^^^^^ the condition
warning: unknown field `Foo`
┌─ tabbed:5:2
5 │ Foo: Bar
│ ^^^ the field

View File

@@ -0,0 +1,23 @@
---
source: codespan-reporting/tests/term.rs
expression: TEST_DATA.emit_no_color(&config)
---
warning: unknown weapon `DogJaw`
┌─ tabbed:3:11
3 │ Weapon: DogJaw
│ ^^^^^^ the weapon
warning: unknown condition `attack-cooldown`
┌─ tabbed:4:23
4 │ ReloadingCondition: attack-cooldown
│ ^^^^^^^^^^^^^^^ the condition
warning: unknown field `Foo`
┌─ tabbed:5:2
5 │ Foo: Bar
│ ^^^ the field

Some files were not shown because too many files have changed in this diff Show More