Commit 63492533 authored by Mark Florisson's avatar Mark Florisson

Better fused types error detection, specialized fused C++ templates

parent 824ec8d6
...@@ -614,7 +614,11 @@ class ExprNode(Node): ...@@ -614,7 +614,11 @@ class ExprNode(Node):
src.entry.used = True src.entry.used = True
return self return self
error(self.pos, "Type is not specific") if src_type.is_fused:
error(self.pos, "Type is not specific")
else:
error(self.pos, "Cannot coerce to a type that is not specialized")
self.type = error_type self.type = error_type
return self return self
......
...@@ -1726,6 +1726,28 @@ class AnalyseExpressionsTransform(CythonTransform): ...@@ -1726,6 +1726,28 @@ class AnalyseExpressionsTransform(CythonTransform):
return node return node
class FindInvalidUseOfFusedTypes(CythonTransform):
def visit_FuncDefNode(self, node):
# Errors related to use in functions with fused args will already
# have been detected
if not node.has_fused_arguments:
if not node.is_generator_body and node.return_type.is_fused:
error(node.pos, "Return type is not specified as argument type")
else:
self.visitchildren(node)
return node
def visit_ExprNode(self, node):
if node.type and node.type.is_fused:
error(node.pos, "Invalid use of fused types, type cannot be specialized")
else:
self.visitchildren(node)
return node
class ExpandInplaceOperators(EnvTransform): class ExpandInplaceOperators(EnvTransform):
def visit_InPlaceAssignmentNode(self, node): def visit_InPlaceAssignmentNode(self, node):
......
...@@ -125,7 +125,7 @@ def create_pipeline(context, mode, exclude_classes=()): ...@@ -125,7 +125,7 @@ def create_pipeline(context, mode, exclude_classes=()):
from Visitor import PrintTree from Visitor import PrintTree
from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
from ParseTreeTransforms import ForwardDeclareTypes, AnalyseDeclarationsTransform from ParseTreeTransforms import ForwardDeclareTypes, AnalyseDeclarationsTransform
from ParseTreeTransforms import AnalyseExpressionsTransform from ParseTreeTransforms import AnalyseExpressionsTransform, FindInvalidUseOfFusedTypes
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
from ParseTreeTransforms import ExpandInplaceOperators, ParallelRangeTransform from ParseTreeTransforms import ExpandInplaceOperators, ParallelRangeTransform
...@@ -187,6 +187,7 @@ def create_pipeline(context, mode, exclude_classes=()): ...@@ -187,6 +187,7 @@ def create_pipeline(context, mode, exclude_classes=()):
IntroduceBufferAuxiliaryVars(context), IntroduceBufferAuxiliaryVars(context),
_check_c_declarations, _check_c_declarations,
AnalyseExpressionsTransform(context), AnalyseExpressionsTransform(context),
FindInvalidUseOfFusedTypes(context),
CreateClosureClasses(context), ## After all lookups and type inference CreateClosureClasses(context), ## After all lookups and type inference
ExpandInplaceOperators(context), ExpandInplaceOperators(context),
OptimizeBuiltinCalls(context), ## Necessary? OptimizeBuiltinCalls(context), ## Necessary?
......
...@@ -50,18 +50,25 @@ class BaseType(object): ...@@ -50,18 +50,25 @@ class BaseType(object):
for attr in subtypes: for attr in subtypes:
list_or_subtype = getattr(self, attr) list_or_subtype = getattr(self, attr)
if list_or_subtype:
if isinstance(list_or_subtype, BaseType): if isinstance(list_or_subtype, BaseType):
list_or_subtype.get_fused_types(result, seen) list_or_subtype.get_fused_types(result, seen)
else: else:
for subtype in list_or_subtype: for subtype in list_or_subtype:
subtype.get_fused_types(result, seen) subtype.get_fused_types(result, seen)
return result return result
return None return None
is_fused = property(get_fused_types, doc="Whether this type or any of its " def _get_fused_types(self):
"""
Add this indirection for the is_fused property to allow overriding
get_fused_types in subclasses.
"""
return self.get_fused_types()
is_fused = property(_get_fused_types, doc="Whether this type or any of its "
"subtypes is a fused type") "subtypes is a fused type")
def __lt__(self, other): def __lt__(self, other):
...@@ -2864,6 +2871,8 @@ class CppClassType(CType): ...@@ -2864,6 +2871,8 @@ class CppClassType(CType):
exception_check = True exception_check = True
namespace = None namespace = None
subtypes = ['templates']
def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None): def __init__(self, name, scope, cname, base_classes, templates = None, template_type = None):
self.name = name self.name = name
self.cname = cname self.cname = cname
......
...@@ -57,10 +57,13 @@ _ERRORS = u""" ...@@ -57,10 +57,13 @@ _ERRORS = u"""
fused_types.pyx:10:15: fused_type does not take keyword arguments fused_types.pyx:10:15: fused_type does not take keyword arguments
fused_types.pyx:15:38: Type specified multiple times fused_types.pyx:15:38: Type specified multiple times
fused_types.pyx:17:33: Cannot fuse a fused type fused_types.pyx:17:33: Cannot fuse a fused type
fused_types.pyx:26:4: Invalid use of fused types, type cannot be specialized
fused_types.pyx:26:4: Not enough types specified to specialize the function, int2_t is still fused fused_types.pyx:26:4: Not enough types specified to specialize the function, int2_t is still fused
fused_types.pyx:27:4: Invalid use of fused types, type cannot be specialized
fused_types.pyx:27:4: Not enough types specified to specialize the function, int2_t is still fused fused_types.pyx:27:4: Not enough types specified to specialize the function, int2_t is still fused
fused_types.pyx:28:16: Call with wrong number of arguments (expected 2, got 1) fused_types.pyx:28:16: Call with wrong number of arguments (expected 2, got 1)
fused_types.pyx:29:16: Call with wrong number of arguments (expected 2, got 3) fused_types.pyx:29:16: Call with wrong number of arguments (expected 2, got 3)
fused_types.pyx:30:4: Invalid use of fused types, type cannot be specialized
fused_types.pyx:30:4: Keyword and starred arguments not allowed in cdef functions. fused_types.pyx:30:4: Keyword and starred arguments not allowed in cdef functions.
fused_types.pyx:36:6: Invalid base type for memoryview slice: int * fused_types.pyx:36:6: Invalid base type for memoryview slice: int *
fused_types.pyx:39:0: Fused lambdas not allowed fused_types.pyx:39:0: Fused lambdas not allowed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment