1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use sway_types::Span;

use crate::{
    error::{err, ok},
    semantic_analysis::{IsConstant, TypedExpression, TypedExpressionVariant},
    type_system::look_up_type_id,
    CompileError, CompileResult,
};

pub(crate) fn instantiate_tuple_index_access(
    parent: TypedExpression,
    index: usize,
    index_span: Span,
    span: Span,
) -> CompileResult<TypedExpression> {
    let mut warnings = vec![];
    let mut errors = vec![];
    let mut tuple_type_arg_to_access = None;
    let type_info = look_up_type_id(parent.return_type);
    let type_args = check!(
        type_info.expect_tuple(parent.span.as_str(), &parent.span),
        return err(warnings, errors),
        warnings,
        errors
    );
    for (pos, type_arg) in type_args.iter().enumerate() {
        if pos == index {
            tuple_type_arg_to_access = Some(type_arg.clone());
        }
    }
    let tuple_type_arg_to_access = match tuple_type_arg_to_access {
        Some(tuple_type_arg_to_access) => tuple_type_arg_to_access,
        None => {
            errors.push(CompileError::TupleIndexOutOfBounds {
                index,
                count: type_args.len(),
                span: index_span,
            });
            return err(warnings, errors);
        }
    };
    let exp = TypedExpression {
        expression: TypedExpressionVariant::TupleElemAccess {
            resolved_type_of_parent: parent.return_type,
            prefix: Box::new(parent),
            elem_to_access_num: index,
            elem_to_access_span: index_span,
        },
        return_type: tuple_type_arg_to_access.type_id,
        is_constant: IsConstant::No,
        span,
    };
    ok(exp, warnings, errors)
}