sway_error/
convert_parse_tree_error.rs

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    /// `//!`.
170    InnerDocComment,
171    /// `///`.
172    OuterDocComment,
173    /// `#[attribute]` or `#![attribute]`.
174    Attribute,
175}
176
177pub(crate) fn get_attribute_type(attribute: &Ident) -> AttributeType {
178    // The doc-comment attribute name has the span that
179    // points to the actual comment line.
180    // Other attributes have spans that point to the actual
181    // attribute name.
182    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}