Skip to content

Commit e7c5b85

Browse files
EmilyBourneyguclu
andauthored
Raise an error for issue pyccel#1339 (pyccel#1866)
Raise an error indicating that C should be used to mix scalar and array return types (see pyccel#1339). --------- Co-authored-by: Yaman Güçlü <[email protected]>
1 parent 1e97f1b commit e7c5b85

File tree

7 files changed

+51
-6
lines changed

7 files changed

+51
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ All notable changes to this project will be documented in this file.
4747
- #1836 : Move `epyccel` module to `pyccel.commands.epyccel` and add support for shortcut import `from pyccel import epyccel`.
4848
- #1720 : functions with the `@inline` decorator are no longer exposed to Python in the shared library.
4949
- #1720 : Error raised when incompatible arguments are passed to an `inlined` function is now fatal.
50+
- #1866 : Raise a more informative error when mixing scalar and array return types.
5051
- \[TESTS\] Filter out cast warnings in cast tests.
5152
- \[INTERNALS\] `FunctionDef` is annotated when it is called, or at the end of the `CodeBlock` if it is never called.
5253
- \[INTERNALS\] `InlinedFunctionDef` is only annotated if it is called.

pyccel/codegen/printing/fcode.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,15 +1875,28 @@ def _print_LiteralString(self, expr):
18751875
return ' // '.join(formatted_str)
18761876

18771877
def _print_Interface(self, expr):
1878+
interface_funcs = expr.functions
1879+
1880+
example_func = interface_funcs[0]
1881+
18781882
# ... we don't print 'hidden' functions
1879-
if expr.functions[0].is_inline:
1883+
if example_func.is_inline:
18801884
return ''
18811885

1886+
if len(example_func.results) == 1:
1887+
if len(set(f.results[0].var.rank == 0 for f in interface_funcs)) != 1:
1888+
message = ("Fortran cannot yet handle a templated function returning either a scalar or an array. "
1889+
"If you are using the terminal interface, please pass --language c, "
1890+
"if you are using the interactive interfaces epyccel or lambdify, please pass language='c'. "
1891+
"See https://github.com/pyccel/pyccel/issues/1339 to monitor the advancement of this issue.")
1892+
errors.report(message,
1893+
severity='error', symbol=expr)
1894+
18821895
name = self._print(expr.name)
1883-
if all(isinstance(f, FunctionAddress) for f in expr.functions):
1884-
funcs = expr.functions
1896+
if all(isinstance(f, FunctionAddress) for f in interface_funcs):
1897+
funcs = interface_funcs
18851898
else:
1886-
funcs = [f for f in expr.functions if f is \
1899+
funcs = [f for f in interface_funcs if f is \
18871900
expr.point([FunctionCallArgument(a.var.clone('arg_'+str(i))) \
18881901
for i,a in enumerate(f.arguments)])]
18891902

pyccel/parser/semantic.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4008,6 +4008,8 @@ def unpack(ann):
40084008
bound_class.add_new_method(func)
40094009

40104010
new_semantic_funcs += [func]
4011+
if expr.python_ast:
4012+
func.set_current_ast(expr.python_ast)
40114013

40124014
if function_call_args is not None and len(new_semantic_funcs) == 0:
40134015
for args in annotated_args[:-1]:
@@ -4026,6 +4028,8 @@ def unpack(ann):
40264028
self.insert_function(f)
40274029

40284030
new_semantic_funcs = Interface(interface_name, new_semantic_funcs, syntactic_node=expr)
4031+
if expr.python_ast:
4032+
new_semantic_funcs.set_current_ast(expr.python_ast)
40294033
if cls_name:
40304034
bound_class.add_new_interface(new_semantic_funcs)
40314035
self.insert_function(new_semantic_funcs)
File renamed without changes.
File renamed without changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# pylint: disable=missing-function-docstring, missing-module-docstring
2+
from pyccel.decorators import types
3+
4+
@types('int')
5+
@types('int[:]')
6+
def f(a):
7+
return a+3

tests/errors/test_errors.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ def test_semantic_non_blocking_developer_errors(f):
133133
error_mode.set_mode('user')
134134
assert errors.has_errors()
135135

136-
@pytest.mark.parametrize("f",get_files_from_folder("codegen/fortran"))
137-
def test_codegen_errors(f):
136+
@pytest.mark.parametrize("f",get_files_from_folder("codegen/fortran_blocking"))
137+
def test_codegen_blocking_errors(f):
138138
# reset Errors singleton
139139
errors = Errors()
140140
errors.reset()
@@ -154,6 +154,26 @@ def test_codegen_errors(f):
154154

155155
assert errors.has_errors()
156156

157+
@pytest.mark.parametrize("f",get_files_from_folder("codegen/fortran_non_blocking"))
158+
def test_codegen_non_blocking_errors(f):
159+
# reset Errors singleton
160+
errors = Errors()
161+
errors.reset()
162+
163+
pyccel = Parser(f)
164+
ast = pyccel.parse()
165+
166+
settings = {}
167+
ast = pyccel.annotate(**settings)
168+
169+
name = os.path.basename(f)
170+
name = os.path.splitext(name)[0]
171+
172+
codegen = Codegen(ast, name, 'fortran')
173+
codegen.printer.doprint(codegen.ast)
174+
175+
assert errors.has_errors()
176+
157177
@pytest.mark.parametrize("f",get_files_from_folder("known_bugs"))
158178
def test_neat_errors_for_known_bugs(f):
159179
# reset Errors singleton

0 commit comments

Comments
 (0)