Skip to content

Commit

Permalink
Checks around ref and mut params of ABIs and Traits (FuelLabs#3573)
Browse files Browse the repository at this point in the history
  • Loading branch information
vaivaswatha authored Dec 12, 2022
1 parent 10e098c commit 5fc1750
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 22 deletions.
4 changes: 2 additions & 2 deletions sway-core/src/semantic_analysis/ast_node/declaration/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl ty::TyAbiDeclaration {
errors
);
for param in &method.parameters {
if param.is_reference && param.is_mutable {
if param.is_reference || param.is_mutable {
errors.push(CompileError::RefMutableNotAllowedInContractAbi {
param_name: param.name.clone(),
})
Expand All @@ -62,7 +62,7 @@ impl ty::TyAbiDeclaration {
errors
);
for param in &method.parameters {
if param.is_reference && param.is_mutable {
if param.is_reference || param.is_mutable {
errors.push(CompileError::RefMutableNotAllowedInContractAbi {
param_name: param.name.clone(),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,17 +700,18 @@ fn type_check_trait_implementation(
{
// TODO use trait constraints as part of the type here to
// implement trait constraint solver */
// check if the mutability of the parameters is incompatible
if impl_method_param.is_mutable != impl_method_signature_param.is_mutable {
errors.push(CompileError::ParameterMutabilityMismatch {
span: impl_method_param.mutability_span.clone(),
});
// Check if we have a non-ref mutable argument. That's not allowed.
if impl_method_signature_param.is_mutable && !impl_method_signature_param.is_reference {
errors.push(CompileError::MutableParameterNotSupported {
param_name: impl_method_signature.name.clone(),
})
}

if (impl_method_param.is_reference || impl_method_signature_param.is_reference)
&& is_contract
// check if reference / mutability of the parameters is incompatible
if impl_method_param.is_mutable != impl_method_signature_param.is_mutable
|| impl_method_param.is_reference != impl_method_signature_param.is_reference
{
errors.push(CompileError::RefMutParameterInContract {
errors.push(CompileError::ParameterRefMutabilityMismatch {
span: impl_method_param.mutability_span.clone(),
});
}
Expand Down
11 changes: 4 additions & 7 deletions sway-error/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub enum CompileError {
MutableParameterNotSupported { param_name: Ident },
#[error("Cannot pass immutable argument to mutable parameter.")]
ImmutableArgumentToMutableParameter { span: Span },
#[error("ref mut parameter is not allowed for contract ABI function.")]
#[error("ref mut or mut parameter is not allowed for contract ABI function.")]
RefMutableNotAllowedInContractAbi { param_name: Ident },
#[error(
"Cannot call associated function \"{fn_name}\" as a method. Use associated function \
Expand Down Expand Up @@ -583,11 +583,9 @@ pub enum CompileError {
span: Span,
},
#[error(
"Parameter mutability mismatch between the trait function declaration and its implementation."
"Parameter reference type or mutability mismatch between the trait function declaration and its implementation."
)]
ParameterMutabilityMismatch { span: Span },
#[error("Ref mutable parameter is not supported for contract ABI function.")]
RefMutParameterInContract { span: Span },
ParameterRefMutabilityMismatch { span: Span },
#[error("Literal value is too large for type {ty}.")]
IntegerTooLarge { span: Span, ty: String },
#[error("Literal value underflows type {ty}.")]
Expand Down Expand Up @@ -841,8 +839,7 @@ impl Spanned for CompileError {
DeclIsNotAConstant { span, .. } => span.clone(),
ImpureInNonContract { span, .. } => span.clone(),
ImpureInPureContext { span, .. } => span.clone(),
ParameterMutabilityMismatch { span, .. } => span.clone(),
RefMutParameterInContract { span, .. } => span.clone(),
ParameterRefMutabilityMismatch { span, .. } => span.clone(),
IntegerTooLarge { span, .. } => span.clone(),
IntegerTooSmall { span, .. } => span.clone(),
IntegerContainsInvalidDigit { span, .. } => span.clone(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
contract;

abi MyContract {
fn test_function(p: u64);
fn test_function1(p1: u64);
fn test_function2(mut p2: u64);
fn test_function3(ref mut p3: u64);
fn test_function4(ref p4: u64);
fn test_function5(p5: u64);
fn test_function6(p6: u64);
}

impl MyContract for Contract {
fn test_function(ref mut p: u64) {
fn test_function1(ref mut p1: u64) {

}
fn test_function2(mut p2: u64) {

}
fn test_function3(ref mut p3: u64) {

}
fn test_function4(ref p4: u64) {

}
fn test_function5(ref p5: u64) {

}
fn test_function6(mut p6: u64) {

}
}

trait MyTrait {
fn check_function1(q1: u64);
fn check_function2(mut q2: u64);
fn check_function3(ref mut q3: u64);
fn check_function4(ref q4: u64);
fn check_function5(q5: u64);
fn check_function6(q6: u64);
}

struct S {

}

impl MyTrait for S {
fn check_function1(ref mut q1: u64) {

}
fn check_function2(mut q2: u64) {

}
fn check_function3(ref mut q3: u64) {

}
fn check_function4(ref q4: u64) {

}
fn check_function5(ref q5: u64) {

}
fn check_function6(mut q6: u64) {

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

# check: $()Ref mutable parameter is not supported for contract ABI function.
# ABI

# check: $()error
# check: $()fn test_function2(mut p2: u64);
# nextln: $()ref mut or mut parameter is not allowed for contract ABI function

# check: $()error
# check: $()fn test_function3(ref mut p3: u64);
# nextln: $()ref mut or mut parameter is not allowed for contract ABI function

# check: $()error
# check: $()fn test_function4(ref p4: u64);
# nextln: $()ref mut or mut parameter is not allowed for contract ABI function

# check: $()error
# check: $()fn test_function1(ref mut p1: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

# check: $()error
# check: $()fn test_function5(ref p5: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

# check: $()error
# check: $()fn test_function6(mut p6: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

#### Trait

# check: $()error
# check: $()fn check_function1(ref mut q1: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

# check: $()error
# check: $()fn check_function2(mut q2: u64);
# nextln: $()This parameter was declared as mutable, which is not supported yet, did you mean to use ref mut?

# check: $()error
# check: $()fn check_function5(ref q5: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

# check: $()error
# check: $()fn check_function6(mut q6: u64) {
# nextln: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation

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

# check: $()fn foo(ref mut x: u64);
# nextln: $()ref mut parameter is not allowed for contract ABI function.
# nextln: $()ref mut or mut parameter is not allowed for contract ABI function.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ category = "fail"
# nextln: $()The definition of this function must match the one in the trait "Foo" declaration.

# check: fn bar(ref mut variable: u64) -> bool {
# check: $()Parameter mutability mismatch between the trait function declaration and its implementation.
# check: $()Parameter reference type or mutability mismatch between the trait function declaration and its implementation.

# check: fn baz() -> u64 {
# nextln: $()expected: u32
Expand Down

0 comments on commit 5fc1750

Please sign in to comment.