Skip to content

Commit

Permalink
Make StructExpression take an Ident instead of a TypeInfo. (Fue…
Browse files Browse the repository at this point in the history
  • Loading branch information
emilyaherbert authored Oct 16, 2022
1 parent 7f587ec commit db34a4e
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 47 deletions.
3 changes: 1 addition & 2 deletions sway-core/src/language/parsed/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{
language::{parsed::CodeBlock, *},
type_system::TypeBinding,
TypeInfo,
};
use sway_types::{ident::Ident, Span, Spanned};

Expand Down Expand Up @@ -44,7 +43,7 @@ pub struct TupleIndexExpression {

#[derive(Debug, Clone)]
pub struct StructExpression {
pub call_path_binding: TypeBinding<CallPath<(TypeInfo, Span)>>,
pub call_path_binding: TypeBinding<CallPath>,
pub fields: Vec<StructExpressionField>,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ impl ty::TyExpression {
let mut warnings = vec![];
let mut errors = vec![];

// type deck the declaration
// type check the declaration
let unknown_decl = check!(
TypeBinding::type_check_with_ident(&mut call_path_binding, ctx.by_ref()),
return err(warnings, errors),
Expand Down Expand Up @@ -825,16 +825,55 @@ impl ty::TyExpression {
#[allow(clippy::too_many_arguments)]
fn type_check_struct_expression(
mut ctx: TypeCheckContext,
call_path_binding: TypeBinding<CallPath<(TypeInfo, Span)>>,
call_path_binding: TypeBinding<CallPath>,
fields: Vec<StructExpressionField>,
span: Span,
) -> CompileResult<ty::TyExpression> {
let mut warnings = vec![];
let mut errors = vec![];

// type check the call path
let TypeBinding {
inner: CallPath {
prefixes, suffix, ..
},
type_arguments,
span: inner_span,
} = call_path_binding;
let type_info = match (suffix.as_str(), type_arguments.is_empty()) {
("Self", true) => TypeInfo::SelfType,
("Self", false) => {
errors.push(CompileError::TypeArgumentsNotAllowed {
span: suffix.span(),
});
return err(warnings, errors);
}
(_, true) => TypeInfo::Custom {
name: suffix,
type_arguments: None,
},
(_, false) => TypeInfo::Custom {
name: suffix,
type_arguments: Some(type_arguments),
},
};

// find the module that the struct decl is in
let type_info_prefix = ctx.namespace.find_module_path(&prefixes);
check!(
ctx.namespace.root().check_submodule(&type_info_prefix),
return err(warnings, errors),
warnings,
errors
);

// resolve the type of the struct decl
let type_id = check!(
call_path_binding.type_check_with_type_info(&mut ctx),
ctx.resolve_type_with_self(
insert_type(type_info),
&inner_span,
EnforceTypeArguments::No,
Some(&type_info_prefix)
),
insert_type(TypeInfo::ErrorRecovery),
warnings,
errors
Expand Down Expand Up @@ -908,7 +947,7 @@ impl ty::TyExpression {
expression: ty::TyExpressionVariant::StructExpression {
struct_name: struct_name.clone(),
fields: typed_fields_buf,
span: call_path_binding.inner.suffix.1.clone(),
span: inner_span,
},
return_type: type_id,
span,
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/node_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ impl Dependencies {
call_path_binding,
fields,
} = &**struct_expression;
self.gather_from_typeinfo(&call_path_binding.inner.suffix.0)
self.gather_from_call_path(&call_path_binding.inner, false, false)
.gather_from_type_arguments(&call_path_binding.type_arguments)
.gather_from_iter(fields.iter(), |deps, field| {
deps.gather_from_expr(&field.value)
Expand Down
31 changes: 10 additions & 21 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2431,52 +2431,41 @@ fn literal_to_literal(
fn path_expr_to_call_path_binding(
ec: &mut ErrorContext,
path_expr: PathExpr,
) -> Result<TypeBinding<CallPath<(TypeInfo, Span)>>, ErrorEmitted> {
) -> Result<TypeBinding<CallPath>, ErrorEmitted> {
let PathExpr {
root_opt,
prefix,
mut suffix,
} = path_expr;
let is_absolute = path_root_opt_to_bool(ec, root_opt)?;
let (prefixes, type_info, type_info_span, type_arguments) = match suffix.pop() {
Some((_double_colon_token, call_path_suffix)) => {
let (prefixes, suffix, span, type_arguments) = match suffix.pop() {
Some((_, call_path_suffix)) => {
let mut prefixes = vec![path_expr_segment_to_ident(ec, prefix)?];
for (_double_colon_token, call_path_prefix) in suffix {
for (_, call_path_prefix) in suffix {
let ident = path_expr_segment_to_ident(ec, call_path_prefix)?;
// note that call paths only support one set of type arguments per call path right
// now
prefixes.push(ident);
}
let span = call_path_suffix.span();
let (suffix, ty_args) =
path_expr_segment_to_ident_or_type_argument(ec, call_path_suffix)?;
let type_info_span = suffix.span();
let type_info = type_name_to_type_info_opt(&suffix).unwrap_or(TypeInfo::Custom {
name: suffix,
type_arguments: None,
});
(prefixes, type_info, type_info_span, ty_args)
(prefixes, suffix, span, ty_args)
}
None => {
let span = prefix.span();
let (suffix, ty_args) = path_expr_segment_to_ident_or_type_argument(ec, prefix)?;
let type_info_span = suffix.span();
let type_info = match type_name_to_type_info_opt(&suffix) {
Some(type_info) => type_info,
None => TypeInfo::Custom {
name: suffix,
type_arguments: None,
},
};
(vec![], type_info, type_info_span, ty_args)
(vec![], suffix, span, ty_args)
}
};
Ok(TypeBinding {
inner: CallPath {
prefixes,
suffix: (type_info, type_info_span.clone()),
suffix,
is_absolute,
},
type_arguments,
span: type_info_span, // TODO: change this span so that it includes the type arguments
span,
})
}

Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/type_system/type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl fmt::Display for TypeId {

impl fmt::Debug for TypeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
f.write_str(&look_up_type_id(*self).to_string())
}
}

Expand Down
1 change: 1 addition & 0 deletions sway-core/src/type_system/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,7 @@ impl TypeInfo {
/// and return its contents.
///
/// Returns an error if `self` is not a `TypeInfo::Struct`.
#[allow(dead_code)]
pub(crate) fn expect_struct(
&self,
debug_span: &Span,
Expand Down
24 changes: 7 additions & 17 deletions sway-lsp/src/core/traverse_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,23 +392,13 @@ fn handle_expression(expression: &Expression, tokens: &TokenMap) {
);
}

if let (
TypeInfo::Custom {
name,
type_arguments,
},
..,
) = &call_path_binding.inner.suffix
{
let token = Token::from_parsed(
AstToken::Expression(expression.clone()),
SymbolKind::Struct,
);
tokens.insert(to_ident_key(name), token.clone());
if let Some(args) = type_arguments {
collect_type_args(args, &token, tokens);
}
}
let name = &call_path_binding.inner.suffix;
let type_arguments = &call_path_binding.type_arguments;

let token =
Token::from_parsed(AstToken::Expression(expression.clone()), SymbolKind::Struct);
tokens.insert(to_ident_key(name), token.clone());
collect_type_args(type_arguments, &token, tokens);

for field in fields {
tokens.insert(
Expand Down

0 comments on commit db34a4e

Please sign in to comment.