1use sway_types::{Ident, IdentUnique, Span, Spanned};
2use thiserror::Error;
3
4use crate::formatting::{
5 a_or_an, num_to_str, num_to_str_or_none, plural_s, sequence_to_str, Enclosing,
6};
7
8#[derive(Error, Debug, Clone, PartialEq, Eq, Hash)]
9pub enum ConvertParseTreeError {
10 #[error("Imports without items are not supported")]
11 ImportsWithoutItemsNotSupported { span: Span },
12 #[error("functions used in applications may not be arbitrary expressions")]
13 FunctionArbitraryExpression { span: Span },
14 #[error("generics are not supported here")]
15 GenericsNotSupportedHere { span: Span },
16 #[error("multiple generics are not supported")]
17 MultipleGenericsNotSupported { span: Span },
18 #[error("tuple index out of range")]
19 TupleIndexOutOfRange { span: Span },
20 #[error("shift-left expressions are not implemented")]
21 ShlNotImplemented { span: Span },
22 #[error("shift-right expressions are not implemented")]
23 ShrNotImplemented { span: Span },
24 #[error("bitwise xor expressions are not implemented")]
25 BitXorNotImplemented { span: Span },
26 #[error("integer literals in this position cannot have a type suffix")]
27 IntTySuffixNotSupported { span: Span },
28 #[error("int literal out of range")]
29 IntLiteralOutOfRange { span: Span },
30 #[error("expected an integer literal")]
31 IntLiteralExpected { span: Span },
32 #[error("qualified path roots are not implemented")]
33 QualifiedPathRootsNotImplemented { span: Span },
34 #[error("char literals are not implemented")]
35 CharLiteralsNotImplemented { span: Span },
36 #[error("hex literals must have 1..16 or 64 digits")]
37 HexLiteralLength { span: Span },
38 #[error("binary literals must have either 1..64 or 256 digits")]
39 BinaryLiteralLength { span: Span },
40 #[error("u8 literal out of range")]
41 U8LiteralOutOfRange { span: Span },
42 #[error("u16 literal out of range")]
43 U16LiteralOutOfRange { span: Span },
44 #[error("u32 literal out of range")]
45 U32LiteralOutOfRange { span: Span },
46 #[error("u64 literal out of range")]
47 U64LiteralOutOfRange { span: Span },
48 #[error("signed integers are not supported")]
49 SignedIntegersNotSupported { span: Span },
50 #[error("ref variables are not supported")]
51 RefVariablesNotSupported { span: Span },
52 #[error("literal patterns not supported in this position")]
53 LiteralPatternsNotSupportedHere { span: Span },
54 #[error("constant patterns not supported in this position")]
55 ConstantPatternsNotSupportedHere { span: Span },
56 #[error("constructor patterns not supported in this position")]
57 ConstructorPatternsNotSupportedHere { span: Span },
58 #[error("struct patterns not supported in this position")]
59 StructPatternsNotSupportedHere { span: Span },
60 #[error("wildcard patterns not supported in this position")]
61 WildcardPatternsNotSupportedHere { span: Span },
62 #[error("or patterns not supported in this position")]
63 OrPatternsNotSupportedHere { span: Span },
64 #[error("tuple patterns not supported in this position")]
65 TuplePatternsNotSupportedHere { span: Span },
66 #[error("ref patterns not supported in this position")]
67 RefPatternsNotSupportedHere { span: Span },
68 #[error("constructor patterns require a single argument")]
69 ConstructorPatternOneArg { span: Span },
70 #[error("constructor patterns cannot contain sub-patterns")]
71 ConstructorPatternSubPatterns { span: Span },
72 #[error("paths are not supported in this position")]
73 PathsNotSupportedHere { span: Span },
74 #[error("Fully specified types are not supported in this position. Try importing the type and referring to it here.")]
75 FullySpecifiedTypesNotSupported { span: Span },
76 #[error("ContractCaller requires exactly one generic argument")]
77 ContractCallerOneGenericArg { span: Span },
78 #[error("ContractCaller requires a named type for its generic argument")]
79 ContractCallerNamedTypeGenericArg { span: Span },
80 #[error("cannot find type \"{ty_name}\" in this scope")]
81 ConstrainedNonExistentType { ty_name: Ident, span: Span },
82 #[error("__get_storage_key does not take arguments")]
83 GetStorageKeyTooManyArgs { span: Span },
84 #[error("recursive types are not supported")]
85 RecursiveType { span: Span },
86 #[error("enum variant \"{name}\" already declared")]
87 DuplicateEnumVariant { name: Ident, span: Span },
88 #[error("storage field \"{name}\" already declared")]
89 DuplicateStorageField { name: Ident, span: Span },
90 #[error("configurable \"{name}\" already declared")]
91 DuplicateConfigurable { name: Ident, span: Span },
92 #[error("Multiple configurable blocks detected in this module")]
93 MultipleConfigurableBlocksInModule { span: Span },
94 #[error("struct field \"{name}\" already declared")]
95 DuplicateStructField { name: Ident, span: Span },
96 #[error("identifier \"{name}\" bound more than once in this parameter list")]
97 DuplicateParameterIdentifier { name: Ident, span: Span },
98 #[error("self parameter is not allowed for {fn_kind}")]
99 SelfParameterNotAllowedForFn { fn_kind: String, span: Span },
100 #[error("`impl Self` for contracts is not supported")]
101 SelfImplForContract { span: Span },
102 #[error("Expected module at the beginning before any other items.")]
103 ExpectedModuleAtBeginning { span: Span },
104 #[error("Constant requires expression.")]
105 ConstantRequiresExpression { span: Span },
106 #[error("Constant requires type ascription.")]
107 ConstantRequiresTypeAscription { span: Span },
108 #[error("Unknown type name \"self\". A self type with a similar name exists (notice the capitalization): `Self`")]
109 UnknownTypeNameSelf { span: Span },
110 #[error("{}", match get_attribute_type(attribute) {
111 AttributeType::InnerDocComment => format!("Inner doc comment (`//!`) cannot document {}{target_friendly_name}.", a_or_an(&target_friendly_name)),
112 AttributeType::OuterDocComment => format!("Outer doc comment (`///`) cannot document {}{target_friendly_name}.", a_or_an(&target_friendly_name)),
113 AttributeType::Attribute => format!("\"{attribute}\" attribute cannot annotate {}{target_friendly_name}.", a_or_an(&target_friendly_name)),
114 })]
115 InvalidAttributeTarget {
116 span: Span,
117 attribute: Ident,
118 target_friendly_name: &'static str,
119 can_only_annotate_help: Vec<&'static str>,
120 },
121 #[error("\"{last_occurrence}\" attribute can be applied only once, but is applied {} times.", num_to_str(previous_occurrences.len() + 1))]
122 InvalidAttributeMultiplicity {
123 last_occurrence: IdentUnique,
124 previous_occurrences: Vec<IdentUnique>,
125 },
126 #[error("\"{attribute}\" attribute must {}, but has {}.", get_expected_attributes_args_multiplicity_msg(args_multiplicity), num_to_str_or_none(*num_of_args))]
127 InvalidAttributeArgsMultiplicity {
128 span: Span,
129 attribute: Ident,
130 args_multiplicity: (usize, usize),
131 num_of_args: usize,
132 },
133 #[error(
134 "\"{arg}\" is an invalid argument for attribute \"{attribute}\". Valid arguments are: {}.",
135 sequence_to_str(expected_args, Enclosing::DoubleQuote, usize::MAX)
136 )]
137 InvalidAttributeArg {
138 attribute: Ident,
139 arg: IdentUnique,
140 expected_args: Vec<&'static str>,
141 },
142 #[error("\"{arg}\" argument of the attribute \"{attribute}\" must {}have a value.",
143 match value_span {
144 Some(_) => "not ",
145 None => "",
146 }
147 )]
148 InvalidAttributeArgExpectsValue {
149 attribute: Ident,
150 arg: IdentUnique,
151 value_span: Option<Span>,
152 },
153 #[error("\"{arg}\" argument must have a value of type \"{expected_type}\".")]
154 InvalidAttributeArgValueType {
155 span: Span,
156 arg: Ident,
157 expected_type: &'static str,
158 received_type: &'static str,
159 },
160 #[error("{} is an invalid value for argument \"{arg}\". Valid values are: {}.", span.as_str(), sequence_to_str(expected_values, Enclosing::DoubleQuote, usize::MAX))]
161 InvalidAttributeArgValue {
162 span: Span,
163 arg: Ident,
164 expected_values: Vec<&'static str>,
165 },
166}
167
168pub(crate) enum AttributeType {
169 InnerDocComment,
171 OuterDocComment,
173 Attribute,
175}
176
177pub(crate) fn get_attribute_type(attribute: &Ident) -> AttributeType {
178 let span = attribute.span();
183 let attribute = span.as_str();
184 if attribute.starts_with("//!") {
185 AttributeType::InnerDocComment
186 } else if attribute.starts_with("///") {
187 AttributeType::OuterDocComment
188 } else {
189 AttributeType::Attribute
190 }
191}
192
193pub(crate) fn get_expected_attributes_args_multiplicity_msg(
194 args_multiplicity: &(usize, usize),
195) -> String {
196 match *args_multiplicity {
197 (0, 0) => "not have any arguments".to_string(),
198 (min, max) if min == max => format!("have exactly {} argument{}", num_to_str(min), plural_s(min)),
199 (min, max) if min == max - 1 => format!("have {} or {} argument{}", num_to_str_or_none(min), num_to_str(max), plural_s(max)),
200 (0, max) if max != usize::MAX => format!("have at most {} argument{}", num_to_str(max), plural_s(max)),
201 (min, usize::MAX) if min != usize::MIN => format!("have at least {} argument{}", num_to_str(min), plural_s(min)),
202 (min, max) if max != usize::MAX => format!("have between {} and {} arguments", num_to_str(min), num_to_str(max)),
203 (0, usize::MAX) => unreachable!("if any number of arguments are accepted the `InvalidAttributeArgsMultiplicity` error cannot occur"),
204 _ => unreachable!("`min` is `always` less than or equal to `max` and all combinations are already covered"),
205 }
206}
207
208impl Spanned for ConvertParseTreeError {
209 fn span(&self) -> Span {
210 match self {
211 ConvertParseTreeError::ImportsWithoutItemsNotSupported { span } => span.clone(),
212 ConvertParseTreeError::FunctionArbitraryExpression { span } => span.clone(),
213 ConvertParseTreeError::GenericsNotSupportedHere { span } => span.clone(),
214 ConvertParseTreeError::MultipleGenericsNotSupported { span } => span.clone(),
215 ConvertParseTreeError::TupleIndexOutOfRange { span } => span.clone(),
216 ConvertParseTreeError::ShlNotImplemented { span } => span.clone(),
217 ConvertParseTreeError::ShrNotImplemented { span } => span.clone(),
218 ConvertParseTreeError::BitXorNotImplemented { span } => span.clone(),
219 ConvertParseTreeError::IntTySuffixNotSupported { span } => span.clone(),
220 ConvertParseTreeError::IntLiteralOutOfRange { span } => span.clone(),
221 ConvertParseTreeError::IntLiteralExpected { span } => span.clone(),
222 ConvertParseTreeError::QualifiedPathRootsNotImplemented { span } => span.clone(),
223 ConvertParseTreeError::CharLiteralsNotImplemented { span } => span.clone(),
224 ConvertParseTreeError::HexLiteralLength { span } => span.clone(),
225 ConvertParseTreeError::BinaryLiteralLength { span } => span.clone(),
226 ConvertParseTreeError::U8LiteralOutOfRange { span } => span.clone(),
227 ConvertParseTreeError::U16LiteralOutOfRange { span } => span.clone(),
228 ConvertParseTreeError::U32LiteralOutOfRange { span } => span.clone(),
229 ConvertParseTreeError::U64LiteralOutOfRange { span } => span.clone(),
230 ConvertParseTreeError::SignedIntegersNotSupported { span } => span.clone(),
231 ConvertParseTreeError::RefVariablesNotSupported { span } => span.clone(),
232 ConvertParseTreeError::LiteralPatternsNotSupportedHere { span } => span.clone(),
233 ConvertParseTreeError::ConstantPatternsNotSupportedHere { span } => span.clone(),
234 ConvertParseTreeError::ConstructorPatternsNotSupportedHere { span } => span.clone(),
235 ConvertParseTreeError::StructPatternsNotSupportedHere { span } => span.clone(),
236 ConvertParseTreeError::WildcardPatternsNotSupportedHere { span } => span.clone(),
237 ConvertParseTreeError::OrPatternsNotSupportedHere { span } => span.clone(),
238 ConvertParseTreeError::TuplePatternsNotSupportedHere { span } => span.clone(),
239 ConvertParseTreeError::RefPatternsNotSupportedHere { span } => span.clone(),
240 ConvertParseTreeError::ConstructorPatternOneArg { span } => span.clone(),
241 ConvertParseTreeError::ConstructorPatternSubPatterns { span } => span.clone(),
242 ConvertParseTreeError::PathsNotSupportedHere { span } => span.clone(),
243 ConvertParseTreeError::FullySpecifiedTypesNotSupported { span } => span.clone(),
244 ConvertParseTreeError::ContractCallerOneGenericArg { span } => span.clone(),
245 ConvertParseTreeError::ContractCallerNamedTypeGenericArg { span } => span.clone(),
246 ConvertParseTreeError::ConstrainedNonExistentType { span, .. } => span.clone(),
247 ConvertParseTreeError::GetStorageKeyTooManyArgs { span, .. } => span.clone(),
248 ConvertParseTreeError::RecursiveType { span } => span.clone(),
249 ConvertParseTreeError::DuplicateEnumVariant { span, .. } => span.clone(),
250 ConvertParseTreeError::DuplicateStorageField { span, .. } => span.clone(),
251 ConvertParseTreeError::DuplicateConfigurable { span, .. } => span.clone(),
252 ConvertParseTreeError::MultipleConfigurableBlocksInModule { span } => span.clone(),
253 ConvertParseTreeError::DuplicateStructField { span, .. } => span.clone(),
254 ConvertParseTreeError::DuplicateParameterIdentifier { span, .. } => span.clone(),
255 ConvertParseTreeError::SelfParameterNotAllowedForFn { span, .. } => span.clone(),
256 ConvertParseTreeError::SelfImplForContract { span, .. } => span.clone(),
257 ConvertParseTreeError::ExpectedModuleAtBeginning { span } => span.clone(),
258 ConvertParseTreeError::ConstantRequiresExpression { span } => span.clone(),
259 ConvertParseTreeError::ConstantRequiresTypeAscription { span } => span.clone(),
260 ConvertParseTreeError::UnknownTypeNameSelf { span } => span.clone(),
261 ConvertParseTreeError::InvalidAttributeTarget { span, .. } => span.clone(),
262 ConvertParseTreeError::InvalidAttributeMultiplicity {
263 last_occurrence: last_attribute,
264 ..
265 } => last_attribute.span(),
266 ConvertParseTreeError::InvalidAttributeArgsMultiplicity { span, .. } => span.clone(),
267 ConvertParseTreeError::InvalidAttributeArg { arg, .. } => arg.span(),
268 ConvertParseTreeError::InvalidAttributeArgExpectsValue { arg, .. } => arg.span(),
269 ConvertParseTreeError::InvalidAttributeArgValueType { span, .. } => span.clone(),
270 ConvertParseTreeError::InvalidAttributeArgValue { span, .. } => span.clone(),
271 }
272 }
273}