Skip to main content

sway_core/
error.rs

1//! Tools related to handling/recovering from Sway compile errors and reporting them to the user.
2
3use sway_types::{Span, Spanned};
4
5use crate::{
6    language::parsed::{Expression, VariableDeclaration},
7    namespace::ModulePath,
8    Engines, GenericArgument, Namespace,
9};
10
11/// Acts as the result of parsing `Declaration`s, `Expression`s, etc.
12/// Some `Expression`s need to be able to create `VariableDeclaration`s,
13/// so this struct is used to "bubble up" those declarations to a viable
14/// place in the AST.
15#[derive(Debug, Clone)]
16pub struct ParserLifter<T> {
17    pub var_decls: Vec<VariableDeclaration>,
18    pub value: T,
19}
20
21impl<T> ParserLifter<T> {
22    #[allow(dead_code)]
23    pub(crate) fn empty(value: T) -> Self {
24        ParserLifter {
25            var_decls: vec![],
26            value,
27        }
28    }
29}
30
31/// When providing suggestions for errors and warnings, a solution for an issue can sometimes
32/// be changing the code in some other module. We want to provide such suggestions only if
33/// the programmer can actually change the code in that module.
34///
35/// Assuming that the issue occurs in the `issue_namespace` to which the programmer has access,
36/// and that fixing it means changing the code in the module given by the `absolute_module_path`
37/// this function returns true if the programmer can change that module.
38pub(crate) fn module_can_be_changed(
39    _engines: &Engines,
40    issue_namespace: &Namespace,
41    absolute_module_path: &ModulePath,
42) -> bool {
43    // For now, we assume that the programmers can change the module
44    // if the module is in the same package where the issue is.
45    // A bit too restrictive, considering the same workspace might be more appropriate,
46    // but it's a good start.
47    !issue_namespace.module_is_external(absolute_module_path)
48}
49
50// Returns the span covering all the arguments of a function or intrinsic function call.
51// If `arguments` are empty, returns `span`.
52pub(crate) fn span_of_arguments(arguments: &[Expression], span: &Span) -> Span {
53    if arguments.is_empty() {
54        span.clone()
55    } else {
56        Span::join_all(arguments.iter().map(|arg| arg.span()))
57    }
58}
59
60// Returns the span covering all the type arguments of a function or intrinsic function call.
61// If `type_arguments` are empty, returns `span`.
62pub(crate) fn span_of_type_arguments(type_arguments: &[GenericArgument], span: &Span) -> Span {
63    if type_arguments.is_empty() {
64        span.clone()
65    } else {
66        Span::join_all(type_arguments.iter().map(|targ| targ.span()))
67    }
68}