diff --git a/Sources/SemanticAnalyzer/SemanticAnalyzer.swift b/Sources/SemanticAnalyzer/SemanticAnalyzer.swift index 4def8cf8..bf9a5801 100644 --- a/Sources/SemanticAnalyzer/SemanticAnalyzer.swift +++ b/Sources/SemanticAnalyzer/SemanticAnalyzer.swift @@ -131,6 +131,13 @@ public struct SemanticAnalyzer: ASTPass { diagnostics.append(.payableFunctionDoesNotHavePayableValueParameter(functionDeclaration)) } } + + if functionDeclaration.isPublic { + let dynamicParameters = functionDeclaration.parameters.filter { $0.type.rawType.isDynamicType && !$0.isImplicit } + if !dynamicParameters.isEmpty { + diagnostics.append(.useOfDynamicParamaterInFunctionDeclaration(functionDeclaration, dynamicParameters: dynamicParameters)) + } + } let statements = functionDeclaration.body diff --git a/Sources/SemanticAnalyzer/SemanticError.swift b/Sources/SemanticAnalyzer/SemanticError.swift index 4393d7c9..2ce42803 100644 --- a/Sources/SemanticAnalyzer/SemanticError.swift +++ b/Sources/SemanticAnalyzer/SemanticError.swift @@ -53,6 +53,11 @@ extension Diagnostic { static func payableFunctionDoesNotHavePayableValueParameter(_ functionDeclaration: FunctionDeclaration) -> Diagnostic { return Diagnostic(severity: .error, sourceLocation: functionDeclaration.sourceLocation, message: "'\(functionDeclaration.identifier.name)' is declared @payable but doesn't have an implicit parameter of a currency type") } + + static func useOfDynamicParamaterInFunctionDeclaration(_ functionDeclaration: FunctionDeclaration, dynamicParameters: [Parameter]) -> Diagnostic { + let notes = dynamicParameters.map { Diagnostic(severity: .note, sourceLocation: $0.sourceLocation, message: "\($0.identifier.name) cannot be used as a parameter") } + return Diagnostic(severity: .error, sourceLocation: functionDeclaration.sourceLocation, message: "Function '\(functionDeclaration.identifier.name)' cannot have dynamic parameters", notes: notes) + } static func ambiguousPayableValueParameter(_ functionDeclaration: FunctionDeclaration) -> Diagnostic { return Diagnostic(severity: .error, sourceLocation: functionDeclaration.sourceLocation, message: "Ambiguous implicit payable value parameter. Only one parameter can be declared implicit with a currency type") diff --git a/Tests/SemanticTests/structs.flint b/Tests/SemanticTests/structs.flint index 2300dabd..0857c2f1 100644 --- a/Tests/SemanticTests/structs.flint +++ b/Tests/SemanticTests/structs.flint @@ -45,4 +45,7 @@ Foo :: (any) { b(&b) b(&self.b) // expected-error {{Function 'b' is not in scope or cannot be called using the caller capability 'any'}} } -} + + public func c(x: inout Test) {} // expected-error {{Function 'c' cannot have dynamic parameters}} + public func d(x: [Int]) {} // expected-error {{Function 'd' cannot have dynamic parameters}} +}