Skip to content

Commit

Permalink
Introduce FromTrait method name (FuelLabs#1684)
Browse files Browse the repository at this point in the history
* Introduce FromTrait method name

* clippy
  • Loading branch information
sezna authored May 26, 2022
1 parent 4b7c4fc commit a08570a
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 73 deletions.
8 changes: 3 additions & 5 deletions sway-core/src/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,8 +1323,8 @@ fn expr_to_expression(ec: &mut ErrorContext, expr: Expr) -> Result<Expression, E
Expression::MethodApplication {
method_name: MethodName::FromType {
call_path,
type_name: Some(type_name),
type_name_span: Some(type_name_span),
type_name,
type_name_span,
},
contract_call_params: Vec::new(),
arguments,
Expand Down Expand Up @@ -1649,7 +1649,7 @@ fn binary_op_call(
rhs: Expr,
) -> Result<Expression, ErrorEmitted> {
Ok(Expression::MethodApplication {
method_name: MethodName::FromType {
method_name: MethodName::FromTrait {
call_path: CallPath {
prefixes: vec![
Ident::new_with_override("core", op_span.clone()),
Expand All @@ -1658,8 +1658,6 @@ fn binary_op_call(
suffix: Ident::new_with_override(name, op_span),
is_absolute: true,
},
type_name: None,
type_name_span: None,
},
contract_call_params: Vec::new(),
arguments: vec![expr_to_expression(ec, lhs)?, expr_to_expression(ec, rhs)?],
Expand Down
15 changes: 12 additions & 3 deletions sway-core/src/parse_tree/expression/method_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ pub enum MethodName {
/// Represents a method lookup with a type somewhere in the path
FromType {
call_path: CallPath,
type_name: Option<TypeInfo>,
type_name_span: Option<Span>,
type_name: TypeInfo,
type_name_span: Span,
},
/// Represents a method lookup that does not contain any types in the path
/// something like a.b(c)
/// in this case, the first argument defines where to look for the method
FromModule { method_name: Ident },
/// something like a::b::c()
/// in this case, the path defines where the fn symbol is defined
/// used for things like core::ops::add(a, b).
/// in this case, the first argument determines the type to look for
FromTrait { call_path: CallPath },
}

impl MethodName {
/// To be used for error messages and debug strings
pub fn easy_name(&self) -> Ident {
match self {
MethodName::FromType { call_path, .. } => call_path.suffix.clone(),
MethodName::FromType { call_path, .. } | MethodName::FromTrait { call_path, .. } => {
call_path.suffix.clone()
}
MethodName::FromModule { method_name, .. } => method_name.clone(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,8 @@ impl TypedExpression {
.to_var_name(),
is_absolute: true,
};
let method_name = MethodName::FromType {
let method_name = MethodName::FromTrait {
call_path: call_path.clone(),
type_name: None,
type_name_span: None,
};
let arguments = VecDeque::from(arguments);
let method = check!(
Expand Down Expand Up @@ -1818,7 +1816,7 @@ impl TypedExpression {
)
} else {
// Otherwise convert into a method call 'index(self, index)' via the std::ops::Index trait.
let method_name = MethodName::FromType {
let method_name = MethodName::FromTrait {
call_path: CallPath {
prefixes: vec![
Ident::new_with_override("core", span.clone()),
Expand All @@ -1827,8 +1825,6 @@ impl TypedExpression {
suffix: Ident::new_with_override("index", span.clone()),
is_absolute: true,
},
type_name: None,
type_name_span: None,
};
type_check_method_application(
method_name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ pub(crate) fn type_check_method_application(
// something like a.b(c)
MethodName::FromModule { method_name } => {
let selector = if method.is_contract_call {
let contract_address = match contract_caller
.map(|x| crate::type_engine::look_up_type_id(x.return_type))
let contract_address = match contract_caller.map(|x| look_up_type_id(x.return_type))
{
Some(TypeInfo::ContractCaller { address, .. }) => address,
_ => {
Expand Down Expand Up @@ -215,7 +214,7 @@ pub(crate) fn type_check_method_application(
}

// something like blah::blah::~Type::foo()
MethodName::FromType { call_path, .. } => {
MethodName::FromType { call_path, .. } | MethodName::FromTrait { call_path } => {
let selector = if method.is_contract_call {
let contract_address = match contract_caller
.map(|x| crate::type_engine::look_up_type_id(x.return_type))
Expand Down Expand Up @@ -280,57 +279,35 @@ pub(crate) fn resolve_method_name(
call_path,
type_name,
type_name_span,
} => {
let (ty, type_name_span): (TypeInfo, Span) = match (type_name, type_name_span) {
(Some(type_name), Some(type_name_span)) => {
(type_name.clone(), type_name_span.clone())
}
_ => arguments
.get(0)
.map(|x| (look_up_type_id(x.return_type), x.span.clone()))
.unwrap_or_else(|| (TypeInfo::Unknown, span.clone())),
};
let ty = match (ty, type_arguments.is_empty()) {
(
TypeInfo::Custom {
name,
type_arguments: type_args,
},
false,
) => {
if type_args.is_empty() {
TypeInfo::Custom {
name,
type_arguments,
}
} else {
let type_args_span = type_args
.iter()
.map(|x| x.span.clone())
.fold(type_args[0].span.clone(), Span::join);
errors.push(CompileError::Internal(
"did not expect to find type arguments here",
type_args_span,
));
return err(warnings, errors);
}
}
(_, false) => {
errors.push(CompileError::DoesNotTakeTypeArguments {
span: type_name_span,
name: call_path.suffix.clone(),
});
return err(warnings, errors);
}
(ty, true) => ty,
};
let abs_path: Vec<Ident> = if call_path.is_absolute {
call_path.full_path().cloned().collect()
} else {
namespace.find_module_path(call_path.full_path())
};
} => check!(
find_method(
type_name,
type_name_span,
type_arguments,
namespace,
&arguments,
call_path,
self_type
),
return err(warnings, errors),
warnings,
errors
),
MethodName::FromTrait { call_path } => {
let (type_name, type_name_span) = arguments
.get(0)
.map(|x| (look_up_type_id(x.return_type), x.span.clone()))
.unwrap_or_else(|| (TypeInfo::Unknown, span.clone()));
check!(
namespace.find_method_for_type(insert_type(ty), &abs_path, self_type, &arguments),
find_method(
&type_name,
&type_name_span,
type_arguments,
namespace,
&arguments,
call_path,
self_type
),
return err(warnings, errors),
warnings,
errors
Expand All @@ -352,3 +329,56 @@ pub(crate) fn resolve_method_name(
};
ok(func_decl, warnings, errors)
}

fn find_method(
type_name: &TypeInfo,
type_name_span: &Span,
type_arguments: Vec<TypeArgument>,
namespace: &mut Namespace,
arguments: &VecDeque<TypedExpression>,
call_path: &CallPath,
self_type: TypeId,
) -> CompileResult<TypedFunctionDeclaration> {
let warnings = vec![];
let mut errors = vec![];
let ty = match (type_name, type_arguments.is_empty()) {
(
TypeInfo::Custom {
name,
type_arguments: type_args,
},
false,
) => {
if type_args.is_empty() {
TypeInfo::Custom {
name: name.clone(),
type_arguments,
}
} else {
let type_args_span = type_args
.iter()
.map(|x| x.span.clone())
.fold(type_args[0].span.clone(), Span::join);
errors.push(CompileError::Internal(
"did not expect to find type arguments here",
type_args_span,
));
return err(warnings, errors);
}
}
(_, false) => {
errors.push(CompileError::DoesNotTakeTypeArguments {
span: type_name_span.clone(),
name: call_path.suffix.clone(),
});
return err(warnings, errors);
}
(ty, true) => ty.clone(),
};
let abs_path: Vec<Ident> = if call_path.is_absolute {
call_path.full_path().cloned().collect()
} else {
namespace.find_module_path(call_path.full_path())
};
namespace.find_method_for_type(insert_type(ty), &abs_path, self_type, arguments)
}
6 changes: 1 addition & 5 deletions sway-lsp/src/core/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,7 @@ fn handle_expression(exp: Expression, tokens: &mut Vec<Token>) {
}

//TODO handle methods from imported modules
if let MethodName::FromType {
type_name: Some(type_name),
..
} = &method_name
{
if let MethodName::FromType { type_name, .. } = &method_name {
handle_custom_type(type_name, tokens);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[package]]
name = 'abort_control_flow'
name = 'abort_control_flow_bad'
dependencies = ['std']

[[package]]
Expand Down

0 comments on commit a08570a

Please sign in to comment.