1use crate::prelude::*;
2use colored::Colorize;
3
4pub mod message;
5pub mod report;
6
7#[derive_group(Serializers)]
8#[derive(Debug, Clone, JsonSchema)]
9pub struct Diagnostics {
10 pub kind: Kind,
11 pub span: Vec<hax_frontend_exporter::Span>,
12 pub context: String,
13 pub owner_id: Option<hax_frontend_exporter::DefId>,
14}
15
16impl std::fmt::Display for Diagnostics {
17 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
18 write!(f, "({}) ", self.context)?;
19 match &self.kind {
20 Kind::Unimplemented { issue_id, details } => write!(
21 f,
22 "something is not implemented yet.{}{}",
23 match issue_id {
24 Some(id) => format!("This is discussed in issue https://github.com/hacspec/hax/issues/{id}.\nPlease upvote or comment this issue if you see this error message."),
25 _ => "".to_string(),
26 },
27 match details {
28 Some(details) => format!("\n{}", details),
29 _ => "".to_string(),
30 }
31 ),
32 Kind::UnsupportedMacro { id } => write!(
33 f,
34 "The unexpanded macro {} it is not supported by this backend. Please verify the option you passed the {} (or {}) option.",
35 id.bold(),
36 "--inline-macro-call".bold(), "-i".bold()
37 ),
38 Kind::UnsafeBlock => write!(f, "Unsafe blocks are not allowed."),
39 Kind::AssertionFailure {details} => write!(
40 f,
41 "Fatal error: something we considered as impossible occurred! {}\nDetails: {}",
42 "Please report this by submitting an issue on GitHub!".bold(),
43 details
44 ),
45 Kind::UnallowedMutRef => write!(
46 f,
47 "The mutation of this {} is not allowed here.",
48 "&mut".bold()
49 ),
50 Kind::ExpectedMutRef => write!(
51 f,
52 "At this position, Hax was expecting an expression of the shape `&mut _`. Hax forbids `f(x)` (where `f` expects a mutable reference as input) when `x` is not a {}{} or when it is a dereference expression.
53
54{}
55",
56 "place expression".bold(),
57 "[1]".bright_black(),
58 "[1]: https://doc.rust-lang.org/reference/expressions.html#place-expressions-and-value-expressions"
59 ),
60 Kind::ClosureMutatesParentBindings {bindings} => write!(
61 f,
62 "The bindings {:?} cannot be mutated here: they don't belong to the closure scope, and this is not allowed.",
63 bindings
64 ),
65 Kind::ArbitraryLHS => write!(f, "Assignation of an arbitrary left-hand side is not supported. `lhs = e` is fine only when `lhs` is a combination of local identifiers, field accessors and index accessors."),
66
67 Kind::AttributeRejected {reason} => write!(f, "Here, this attribute cannot be used: {reason}."),
68
69 Kind::NonTrivialAndMutFnInput => write!(f, "The support in hax of function with one or more inputs of type `&mut _` is limited. Onlu trivial patterns are allowed there: `fn f(x: &mut (T, U)) ...` is allowed while `f((x, y): &mut (T, U))` is rejected."),
70
71 Kind::FStarParseError { fstar_snippet, details: _ } => write!(f, "The following code snippet could not be parsed as valid F*:\n```\n{fstar_snippet}\n```"),
72
73 _ => write!(f, "{:?}", self.kind),
74 }
75 }
76}
77
78#[derive_group(Serializers)]
79#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, JsonSchema)]
80#[repr(u16)]
81pub enum Kind {
82 UnsafeBlock = 0,
84
85 Unimplemented {
87 issue_id: Option<u32>,
89 details: Option<String>,
90 } = 1,
91
92 AssertionFailure {
96 details: String,
97 } = 2,
98
99 UnallowedMutRef = 3,
101
102 UnsupportedMacro {
104 id: String,
105 } = 4,
106
107 ErrorParsingMacroInvocation {
109 macro_id: String,
110 details: String,
111 } = 5,
112
113 ClosureMutatesParentBindings {
115 bindings: Vec<String>,
116 } = 6,
117
118 ArbitraryLHS = 7,
120
121 ExplicitRejection {
123 reason: String,
124 } = 8,
125
126 UnsupportedTupleSize {
128 tuple_size: u32,
129 reason: String,
130 } = 9,
131
132 ExpectedMutRef = 10,
133
134 NonTrivialAndMutFnInput = 11,
136
137 AttributeRejected {
139 reason: String,
140 } = 12,
141
142 FStarParseError {
144 fstar_snippet: String,
145 details: String,
146 } = 13,
147}
148
149impl Kind {
150 pub fn discriminant(&self) -> u16 {
152 unsafe { *(self as *const Self as *const u16) }
153 }
154
155 pub fn code(&self) -> String {
156 format!("HAX{:0>4}", self.discriminant())
157 }
158}