Skip to content

Commit

Permalink
Disable self parameters for ABI methods (FuelLabs#3662)
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-trunov authored Dec 30, 2022
1 parent 460c9ca commit 9a0e658
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 13 deletions.
52 changes: 42 additions & 10 deletions sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,11 @@ fn item_to_ast_nodes(
ItemKind::Fn(item_fn) => {
let function_declaration =
item_fn_to_function_declaration(handler, engines, item_fn, attributes)?;
for param in &function_declaration.parameters {
if matches!(param.type_info, TypeInfo::SelfType) {
let error = ConvertParseTreeError::SelfParameterNotAllowedForFreeFn {
span: param.type_span.clone(),
};
return Err(handler.emit_err(error.into()));
}
}
error_if_self_param_is_not_allowed(
handler,
&function_declaration.parameters,
"a free function",
)?;
decl(Declaration::FunctionDeclaration(function_declaration))
}
ItemKind::Trait(item_trait) => decl(Declaration::TraitDeclaration(
Expand Down Expand Up @@ -625,7 +622,14 @@ fn item_abi_to_abi_declaration(
.into_iter()
.map(|(fn_signature, _semicolon_token)| {
let attributes = item_attrs_to_map(handler, &fn_signature.attribute_list)?;
fn_signature_to_trait_fn(handler, engines, fn_signature.value, attributes)
let trait_fn =
fn_signature_to_trait_fn(handler, engines, fn_signature.value, attributes)?;
error_if_self_param_is_not_allowed(
handler,
&trait_fn.parameters,
"an ABI method signature",
)?;
Ok(trait_fn)
})
.collect::<Result<_, _>>()?
},
Expand All @@ -636,7 +640,18 @@ fn item_abi_to_abi_declaration(
.into_iter()
.map(|item_fn| {
let attributes = item_attrs_to_map(handler, &item_fn.attribute_list)?;
item_fn_to_function_declaration(handler, engines, item_fn.value, attributes)
let function_declaration = item_fn_to_function_declaration(
handler,
engines,
item_fn.value,
attributes,
)?;
error_if_self_param_is_not_allowed(
handler,
&function_declaration.parameters,
"a method provided by ABI",
)?;
Ok(function_declaration)
})
.collect::<Result<_, _>>()?,
},
Expand Down Expand Up @@ -3306,3 +3321,20 @@ fn item_attrs_to_map(
}
Ok(Arc::new(attrs_map))
}

fn error_if_self_param_is_not_allowed(
handler: &Handler,
parameters: &[FunctionParameter],
fn_kind: &str,
) -> Result<(), ErrorEmitted> {
for param in parameters {
if matches!(param.type_info, TypeInfo::SelfType) {
let error = ConvertParseTreeError::SelfParameterNotAllowedForFn {
fn_kind: fn_kind.to_owned(),
span: param.type_span.clone(),
};
return Err(handler.emit_err(error.into()));
}
}
Ok(())
}
6 changes: 3 additions & 3 deletions sway-error/src/convert_parse_tree_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ pub enum ConvertParseTreeError {
DuplicateStructField { name: Ident, span: Span },
#[error("identifier \"{name}\" bound more than once in this parameter list")]
DuplicateParameterIdentifier { name: Ident, span: Span },
#[error("self parameter is not allowed for a free function")]
SelfParameterNotAllowedForFreeFn { span: Span },
#[error("self parameter is not allowed for {fn_kind}")]
SelfParameterNotAllowedForFn { fn_kind: String, span: Span },
#[error("test functions are only allowed at module level")]
TestFnOnlyAllowedAtModuleLevel { span: Span },
#[error("`impl Self` for contracts is not supported")]
Expand Down Expand Up @@ -143,7 +143,7 @@ impl Spanned for ConvertParseTreeError {
ConvertParseTreeError::DuplicateStorageField { span, .. } => span.clone(),
ConvertParseTreeError::DuplicateStructField { span, .. } => span.clone(),
ConvertParseTreeError::DuplicateParameterIdentifier { span, .. } => span.clone(),
ConvertParseTreeError::SelfParameterNotAllowedForFreeFn { span, .. } => span.clone(),
ConvertParseTreeError::SelfParameterNotAllowedForFn { span, .. } => span.clone(),
ConvertParseTreeError::TestFnOnlyAllowedAtModuleLevel { span } => span.clone(),
ConvertParseTreeError::SelfImplForContract { span, .. } => span.clone(),
ConvertParseTreeError::CannotDocCommentDependency { span } => span.clone(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[package]]
name = 'no_self_in_abi_method_signature'
source = 'member'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
implicit-std = false
license = "Apache-2.0"
name = "no_self_in_abi_method_signature"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
contract;

abi MyContract {
fn foo(self);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
category = "fail"

# check: $()self parameter is not allowed for an ABI method signature
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[[package]]
name = 'no_self_in_method_provided_by_abi'
source = 'member'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
authors = ["Fuel Labs <[email protected]>"]
entry = "main.sw"
implicit-std = false
license = "Apache-2.0"
name = "no_self_in_method_provided_by_abi"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
contract;

abi MyContract {
fn foo();
} {
fn bar(self) {
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
category = "fail"

# check: $()self parameter is not allowed for a method provided by ABI

0 comments on commit 9a0e658

Please sign in to comment.