Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
11915abb
Commit
11915abb
authored
Dec 04, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce 'iso' qualifier and 'consume' keyword
parent
b24fad38
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
198 additions
and
12 deletions
+198
-12
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+85
-9
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+10
-1
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+44
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+57
-0
Cython/Compiler/TypeInference.py
Cython/Compiler/TypeInference.py
+2
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
11915abb
...
@@ -1048,11 +1048,15 @@ class ExprNode(Node):
...
@@ -1048,11 +1048,15 @@ class ExprNode(Node):
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
src
=
CoerceToComplexNode
(
src
,
dst_type
,
env
)
else
:
else
:
# neither src nor dst are py types
# neither src nor dst are py types
# Qualified cypclass types can have nontrivial aliasing rules
# meaning type equality may not imply the coercion is valid.
if
src_type
.
is_qualified_cyp_class
and
not
dst_type
.
assignable_from
(
src_type
):
self
.
fail_assignment
(
dst_type
)
# Added the string comparison, since for c types that
# Added the string comparison, since for c types that
# is enough, but Cython gets confused when the types are
# is enough, but Cython gets confused when the types are
# in different pxi files.
# in different pxi files.
# TODO: Remove this hack and require shared declarations.
# TODO: Remove this hack and require shared declarations.
if
not
(
src
.
type
==
dst_type
or
str
(
src
.
type
)
==
str
(
dst_type
)
or
dst_type
.
assignable_from
(
src_type
)):
el
if
not
(
src
.
type
==
dst_type
or
str
(
src
.
type
)
==
str
(
dst_type
)
or
dst_type
.
assignable_from
(
src_type
)):
self
.
fail_assignment
(
dst_type
)
self
.
fail_assignment
(
dst_type
)
return
src
return
src
...
@@ -3945,8 +3949,8 @@ class IndexNode(_IndexingBaseNode):
...
@@ -3945,8 +3949,8 @@ class IndexNode(_IndexingBaseNode):
elif
self
.
exception_check
==
'~'
:
elif
self
.
exception_check
==
'~'
:
self
.
is_temp
=
True
self
.
is_temp
=
True
self
.
index
=
self
.
index
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
index
=
self
.
index
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
if
setting
and
not
func_type
.
return_
type
.
is_reference
:
if
setting
and
not
self
.
type
.
is_reference
:
error
(
self
.
pos
,
"Can't set non-reference result '%s'"
%
self
.
type
)
error
(
self
.
pos
,
"Can't set non-reference result '%s'"
%
self
.
type
)
return
self
return
self
...
@@ -3979,7 +3983,7 @@ class IndexNode(_IndexingBaseNode):
...
@@ -3979,7 +3983,7 @@ class IndexNode(_IndexingBaseNode):
self
.
is_temp
=
True
self
.
is_temp
=
True
self
.
index
=
self
.
index
.
coerce_to
(
function
.
type
.
args
[
0
].
type
,
env
)
self
.
index
=
self
.
index
.
coerce_to
(
function
.
type
.
args
[
0
].
type
,
env
)
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
return
self
return
self
def
analyse_cyp_class_setitem
(
self
,
env
):
def
analyse_cyp_class_setitem
(
self
,
env
):
...
@@ -4019,7 +4023,7 @@ class IndexNode(_IndexingBaseNode):
...
@@ -4019,7 +4023,7 @@ class IndexNode(_IndexingBaseNode):
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CppExceptionConversion"
,
"CppSupport.cpp"
))
env
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CppExceptionConversion"
,
"CppSupport.cpp"
))
self
.
index
=
self
.
index
.
coerce_to
(
function
.
type
.
args
[
0
].
type
,
env
)
self
.
index
=
self
.
index
.
coerce_to
(
function
.
type
.
args
[
0
].
type
,
env
)
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
return
self
return
self
def
analyse_as_c_function
(
self
,
env
):
def
analyse_as_c_function
(
self
,
env
):
...
@@ -6234,7 +6238,7 @@ class SimpleCallNode(CallNode):
...
@@ -6234,7 +6238,7 @@ class SimpleCallNode(CallNode):
else
:
else
:
self
.
type
=
PyrexTypes
.
CPtrType
(
self
.
function
.
class_type
)
self
.
type
=
PyrexTypes
.
CPtrType
(
self
.
function
.
class_type
)
else
:
else
:
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
if
self
.
function
.
is_name
or
self
.
function
.
is_attribute
:
if
self
.
function
.
is_name
or
self
.
function
.
is_attribute
:
func_entry
=
self
.
function
.
entry
func_entry
=
self
.
function
.
entry
...
@@ -6723,7 +6727,7 @@ class PythonCapiCallNode(SimpleCallNode):
...
@@ -6723,7 +6727,7 @@ class PythonCapiCallNode(SimpleCallNode):
def
__init__
(
self
,
pos
,
function_name
,
func_type
,
def
__init__
(
self
,
pos
,
function_name
,
func_type
,
utility_code
=
None
,
py_name
=
None
,
**
kwargs
):
utility_code
=
None
,
py_name
=
None
,
**
kwargs
):
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
self
.
result_ctype
=
self
.
type
self
.
result_ctype
=
self
.
type
self
.
function
=
PythonCapiFunctionNode
(
self
.
function
=
PythonCapiFunctionNode
(
pos
,
py_name
,
function_name
,
func_type
,
pos
,
py_name
,
function_name
,
func_type
,
...
@@ -11346,6 +11350,78 @@ class SizeofVarNode(SizeofNode):
...
@@ -11346,6 +11350,78 @@ class SizeofVarNode(SizeofNode):
pass
pass
class
ConsumeNode
(
ExprNode
):
# Consume expression
#
# operand ExprNode
subexprs
=
[
'operand'
]
generate_runtime_check
=
True
operand_is_named
=
True
def
infer_type
(
self
,
env
):
operand_type
=
self
.
operand
.
infer_type
(
env
)
if
operand_type
.
is_cyp_class
:
return
PyrexTypes
.
cyp_class_qualified_type
(
operand_type
,
'iso~'
)
else
:
return
operand_type
def
analyse_types
(
self
,
env
):
self
.
operand
=
self
.
operand
.
analyse_types
(
env
)
operand_type
=
self
.
operand
.
type
if
not
operand_type
.
is_cyp_class
:
error
(
self
.
pos
,
"Can only consume cypclass"
)
self
.
type
=
PyrexTypes
.
error_type
return
self
if
self
.
operand
.
is_name
or
self
.
operand
.
is_attribute
:
self
.
is_temp
=
self
.
operand_is_named
=
True
# We steal the reference of the operand.
self
.
use_managed_ref
=
False
if
operand_type
.
is_qualified_cyp_class
:
if
operand_type
.
qualifier
==
'iso!'
:
error
(
self
.
pos
,
"Cannot consume iso!"
)
self
.
type
=
PyrexTypes
.
error_type
return
self
self
.
generate_runtime_check
=
operand_type
.
qualifier
not
in
(
'iso'
,
'iso~'
)
if
operand_type
.
qualifier
==
'iso~'
:
self
.
type
=
operand_type
else
:
self
.
type
=
PyrexTypes
.
cyp_class_qualified_type
(
operand_type
.
qual_base_type
,
'iso~'
)
else
:
self
.
type
=
PyrexTypes
.
cyp_class_qualified_type
(
operand_type
,
'iso~'
)
return
self
def
may_be_none
(
self
):
return
self
.
operand
.
may_be_none
()
def
is_simple
(
self
):
return
self
.
operand
.
is_simple
()
def
make_owned_reference
(
self
,
code
):
# We steal the reference of the consumed operand.
pass
def
calculate_result_code
(
self
):
if
self
.
generate_runtime_check
:
# TODO: generate runtime check for isolation
return
self
.
operand
.
result
()
else
:
return
self
.
operand
.
result
()
def
generate_result_code
(
self
,
code
):
if
self
.
is_temp
:
operand_result
=
self
.
operand
.
result
()
code
.
putln
(
"%s = %s;"
%
(
self
.
result
(),
operand_result
))
if
self
.
generate_runtime_check
:
# TODO: generate runtime check for isolation
pass
# We steal the reference of the operand.
code
.
putln
(
"%s = NULL;"
%
operand_result
)
if
self
.
operand
.
is_temp
:
# TODO: steal the reference of the operand instead
code
.
put_incref
(
self
.
result
(),
self
.
type
)
class
TypeidNode
(
ExprNode
):
class
TypeidNode
(
ExprNode
):
# C++ typeid operator applied to a type or variable
# C++ typeid operator applied to a type or variable
#
#
...
@@ -11634,7 +11710,7 @@ class BinopNode(ExprNode):
...
@@ -11634,7 +11710,7 @@ class BinopNode(ExprNode):
else
:
else
:
self
.
operand1
=
self
.
operand1
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
operand1
=
self
.
operand1
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
operand2
=
self
.
operand2
.
coerce_to
(
func_type
.
args
[
1
].
type
,
env
)
self
.
operand2
=
self
.
operand2
.
coerce_to
(
func_type
.
args
[
1
].
type
,
env
)
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
def
result_type
(
self
,
type1
,
type2
,
env
):
def
result_type
(
self
,
type1
,
type2
,
env
):
if
self
.
is_pythran_operation_types
(
type1
,
type2
,
env
):
if
self
.
is_pythran_operation_types
(
type1
,
type2
,
env
):
...
@@ -13330,7 +13406,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
...
@@ -13330,7 +13406,7 @@ class PrimaryCmpNode(ExprNode, CmpNode):
else
:
else
:
self
.
operand1
=
self
.
operand1
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
operand1
=
self
.
operand1
.
coerce_to
(
func_type
.
args
[
0
].
type
,
env
)
self
.
operand2
=
self
.
operand2
.
coerce_to
(
func_type
.
args
[
1
].
type
,
env
)
self
.
operand2
=
self
.
operand2
.
coerce_to
(
func_type
.
args
[
1
].
type
,
env
)
self
.
type
=
func_type
.
return_type
self
.
type
=
func_type
.
return_type
.
as_returned_type
()
def
analyse_memoryviewslice_comparison
(
self
,
env
):
def
analyse_memoryviewslice_comparison
(
self
,
env
):
have_none
=
self
.
operand1
.
is_none
or
self
.
operand2
.
is_none
have_none
=
self
.
operand1
.
is_none
or
self
.
operand2
.
is_none
...
...
Cython/Compiler/Parsing.py
View file @
11915abb
...
@@ -309,6 +309,8 @@ def _p_factor(s):
...
@@ -309,6 +309,8 @@ def _p_factor(s):
return
p_typecast
(
s
)
return
p_typecast
(
s
)
elif
sy
==
'IDENT'
and
s
.
systring
==
"sizeof"
:
elif
sy
==
'IDENT'
and
s
.
systring
==
"sizeof"
:
return
p_sizeof
(
s
)
return
p_sizeof
(
s
)
elif
sy
==
'IDENT'
and
s
.
systring
==
"consume"
:
return
p_consume
(
s
)
return
p_power
(
s
)
return
p_power
(
s
)
def
p_typecast
(
s
):
def
p_typecast
(
s
):
...
@@ -357,6 +359,13 @@ def p_sizeof(s):
...
@@ -357,6 +359,13 @@ def p_sizeof(s):
s
.
expect
(
')'
)
s
.
expect
(
')'
)
return
node
return
node
def
p_consume
(
s
):
# s.sy == ident "consume"
pos
=
s
.
position
()
s
.
next
()
operand
=
p_factor
(
s
)
return
ExprNodes
.
ConsumeNode
(
pos
,
operand
=
operand
)
def
p_yield_expression
(
s
):
def
p_yield_expression
(
s
):
# s.sy == "yield"
# s.sy == "yield"
...
@@ -2535,7 +2544,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
...
@@ -2535,7 +2544,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
# Handle cypclass qualifiers
# Handle cypclass qualifiers
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'active'
,):
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'active'
,
'iso'
):
qualifier
=
s
.
systring
qualifier
=
s
.
systring
s
.
next
()
s
.
next
()
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
11915abb
...
@@ -228,6 +228,9 @@ class PyrexType(BaseType):
...
@@ -228,6 +228,9 @@ class PyrexType(BaseType):
# Coerces array and C function types into pointer type for use as
# Coerces array and C function types into pointer type for use as
# a formal argument type.
# a formal argument type.
#
#
# as_returned_type():
# Potentially annotates function call return types as pure rvalues.
#
is_pyobject
=
0
is_pyobject
=
0
is_unspecified
=
0
is_unspecified
=
0
...
@@ -316,6 +319,9 @@ class PyrexType(BaseType):
...
@@ -316,6 +319,9 @@ class PyrexType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
return
self
def
as_returned_type
(
self
):
return
self
def
is_complete
(
self
):
def
is_complete
(
self
):
# A type is incomplete if it is an unsized array,
# A type is incomplete if it is an unsized array,
# a struct whose attributes are not defined, etc.
# a struct whose attributes are not defined, etc.
...
@@ -648,6 +654,12 @@ class CheckedResultType(BaseType):
...
@@ -648,6 +654,12 @@ class CheckedResultType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
.
checked_base_type
.
as_argument_type
()
return
self
.
checked_base_type
.
as_argument_type
()
def
as_returned_type
(
self
):
returned_base_type
=
self
.
checked_base_type
.
as_returned_type
()
if
returned_base_type
.
same_as
(
self
.
checked_base_type
):
return
self
return
CheckedResultType
(
self
.
pos
,
returned_base_type
)
def
cast_code
(
self
,
expr_code
):
def
cast_code
(
self
,
expr_code
):
return
self
.
checked_base_type
.
cast_code
(
expr_code
)
return
self
.
checked_base_type
.
cast_code
(
expr_code
)
...
@@ -1265,6 +1277,9 @@ class BufferType(BaseType):
...
@@ -1265,6 +1277,9 @@ class BufferType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
return
self
def
as_returned_type
(
self
):
return
self
def
specialize
(
self
,
values
):
def
specialize
(
self
,
values
):
dtype
=
self
.
dtype
.
specialize
(
values
)
dtype
=
self
.
dtype
.
specialize
(
values
)
if
dtype
is
not
self
.
dtype
:
if
dtype
is
not
self
.
dtype
:
...
@@ -1956,6 +1971,9 @@ class QualifiedMethodType(BaseType):
...
@@ -1956,6 +1971,9 @@ class QualifiedMethodType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
c_ptr_type
(
self
)
return
c_ptr_type
(
self
)
def
as_returned_type
(
self
):
return
self
# All that follows is just to behave exactly like the underlying function type
# All that follows is just to behave exactly like the underlying function type
def
__getattr__
(
self
,
name
):
def
__getattr__
(
self
,
name
):
...
@@ -3000,6 +3018,13 @@ class CReferenceType(BaseType):
...
@@ -3000,6 +3018,13 @@ class CReferenceType(BaseType):
else
:
else
:
return
type
(
self
)(
base_type
)
return
type
(
self
)(
base_type
)
def
as_returned_type
(
self
):
returned_base_type
=
self
.
ref_base_type
.
as_returned_type
()
if
returned_base_type
==
self
.
ref_base_type
:
return
self
else
:
return
CReferenceType
(
returned_base_type
)
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
return
self
.
ref_base_type
.
deduce_template_params
(
actual
)
return
self
.
ref_base_type
.
deduce_template_params
(
actual
)
...
@@ -4618,6 +4643,8 @@ class CypClassType(CppClassType):
...
@@ -4618,6 +4643,8 @@ class CypClassType(CppClassType):
def
assignable_from_resolved_type
(
self
,
other_type
):
def
assignable_from_resolved_type
(
self
,
other_type
):
if
other_type
.
is_const_cyp_class
:
if
other_type
.
is_const_cyp_class
:
return
0
return
0
if
other_type
.
is_qualified_cyp_class
and
other_type
.
qualifier
!=
'iso~'
:
return
0
if
other_type
.
is_ptr
and
other_type
.
base_type
.
is_cpp_class
and
other_type
.
base_type
.
is_subclass
(
self
)
or
other_type
.
is_null_ptr
:
if
other_type
.
is_ptr
and
other_type
.
base_type
.
is_cpp_class
and
other_type
.
base_type
.
is_subclass
(
self
)
or
other_type
.
is_null_ptr
:
return
1
return
1
return
super
(
CypClassType
,
self
).
assignable_from_resolved_type
(
other_type
)
return
super
(
CypClassType
,
self
).
assignable_from_resolved_type
(
other_type
)
...
@@ -4733,6 +4760,9 @@ class ConstCypclassType(BaseType):
...
@@ -4733,6 +4760,9 @@ class ConstCypclassType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
return
self
def
as_returned_type
(
self
):
return
self
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
return
self
.
const_base_type
.
deduce_template_params
(
actual
)
return
self
.
const_base_type
.
deduce_template_params
(
actual
)
...
@@ -4772,13 +4802,20 @@ class ConstCypclassType(BaseType):
...
@@ -4772,13 +4802,20 @@ class ConstCypclassType(BaseType):
class
QualifiedCypclassType
(
BaseType
):
class
QualifiedCypclassType
(
BaseType
):
"A qualified cypclass reference"
"A qualified cypclass reference"
# qualifier string the qualifier keyword
# qualifier string the qualifier keyword
: ('active' | 'iso' | 'iso~' | 'iso!' )
subtypes
=
[
'qual_base_type'
]
subtypes
=
[
'qual_base_type'
]
is_cyp_class
=
1
is_cyp_class
=
1
is_qualified_cyp_class
=
1
is_qualified_cyp_class
=
1
assignable_to
=
{
'active'
:
(
'active'
,
'iso~'
),
'iso'
:
(
'iso~'
,),
'iso~'
:
(),
'iso!'
:
(),
}
def
__init__
(
self
,
base_type
,
qualifier
):
def
__init__
(
self
,
base_type
,
qualifier
):
assert
base_type
.
is_cyp_class
assert
base_type
.
is_cyp_class
self
.
qual_base_type
=
base_type
self
.
qual_base_type
=
base_type
...
@@ -4830,6 +4867,11 @@ class QualifiedCypclassType(BaseType):
...
@@ -4830,6 +4867,11 @@ class QualifiedCypclassType(BaseType):
def
as_argument_type
(
self
):
def
as_argument_type
(
self
):
return
self
return
self
def
as_returned_type
(
self
):
if
self
.
qualifier
==
'iso'
:
return
QualifiedCypclassType
(
self
.
qual_base_type
,
'iso~'
)
return
self
def
deduce_template_params
(
self
,
actual
):
def
deduce_template_params
(
self
,
actual
):
return
self
.
qual_base_type
.
deduce_template_params
(
actual
)
return
self
.
qual_base_type
.
deduce_template_params
(
actual
)
...
@@ -4848,7 +4890,7 @@ class QualifiedCypclassType(BaseType):
...
@@ -4848,7 +4890,7 @@ class QualifiedCypclassType(BaseType):
return
self
.
assignable_from_resolved_type
(
src_type
.
resolve
())
return
self
.
assignable_from_resolved_type
(
src_type
.
resolve
())
def
assignable_from_resolved_type
(
self
,
src_type
):
def
assignable_from_resolved_type
(
self
,
src_type
):
if
src_type
.
is_qualified_cyp_class
and
s
elf
.
qualifier
==
src_type
.
qualifier
:
if
src_type
.
is_qualified_cyp_class
and
s
rc_type
.
qualifier
in
self
.
assignable_to
[
self
.
qualifier
]
:
return
self
.
qual_base_type
.
assignable_from_resolved_type
(
src_type
.
qual_base_type
)
return
self
.
qual_base_type
.
assignable_from_resolved_type
(
src_type
.
qual_base_type
)
return
0
return
0
...
...
Cython/Compiler/Symtab.py
View file @
11915abb
...
@@ -3272,6 +3272,8 @@ class QualifiedCypclassScope(Scope):
...
@@ -3272,6 +3272,8 @@ class QualifiedCypclassScope(Scope):
def
qualified_cypclass_scope
(
base_type_scope
,
qualifier
):
def
qualified_cypclass_scope
(
base_type_scope
,
qualifier
):
if
qualifier
==
'active'
:
if
qualifier
==
'active'
:
return
ActiveCypclassScope
(
base_type_scope
)
return
ActiveCypclassScope
(
base_type_scope
)
elif
qualifier
.
startswith
(
'iso'
):
return
IsoCypclassScope
(
base_type_scope
)
else
:
else
:
return
QualifiedCypclassScope
(
base_type_scope
,
qualifier
)
return
QualifiedCypclassScope
(
base_type_scope
,
qualifier
)
...
@@ -3293,6 +3295,61 @@ class ActiveCypclassScope(QualifiedCypclassScope):
...
@@ -3293,6 +3295,61 @@ class ActiveCypclassScope(QualifiedCypclassScope):
return
base_entry
.
active_entry
return
base_entry
.
active_entry
class
IsoCypclassScope
(
QualifiedCypclassScope
):
def
__init__
(
self
,
base_type_scope
):
QualifiedCypclassScope
.
__init__
(
self
,
base_type_scope
,
'iso'
)
def
adapt
(
self
,
fieldtype
,
qualifier
=
'iso'
):
if
fieldtype
.
is_qualified_cyp_class
:
# attribute is sendable (either 'iso' or 'active')
return
fieldtype
elif
fieldtype
.
is_cyp_class
:
# viewpoint adaptation
return
PyrexTypes
.
cyp_class_qualified_type
(
fieldtype
,
qualifier
)
else
:
return
fieldtype
def
adapt_arg_type
(
self
,
arg
):
arg
=
copy
.
copy
(
arg
)
arg
.
type
=
self
.
adapt
(
arg
.
type
)
return
arg
def
adapt_method_entry
(
self
,
base_entry
):
iso_method_type
=
copy
.
copy
(
base_entry
.
type
)
# The return type should be treated as 'iso' but cannot be consumed
return_type
=
self
.
adapt
(
base_entry
.
type
.
return_type
,
qualifier
=
'iso!'
)
iso_method_type
.
return_type
=
return_type
iso_method_type
.
args
=
[
self
.
adapt_arg_type
(
arg
)
for
arg
in
base_entry
.
type
.
args
]
if
hasattr
(
base_entry
.
type
,
'op_arg_struct'
):
iso_method_type
.
op_arg_struct
=
entry
.
type
.
op_arg_struct
entry
=
copy
.
copy
(
base_entry
)
entry
.
type
=
iso_method_type
return
entry
def
resolve
(
self
,
name
):
base_entry
=
self
.
base_type_scope
.
lookup_here
(
name
)
if
base_entry
is
None
:
return
None
if
base_entry
.
is_type
:
return
base_entry
if
base_entry
.
is_cfunction
:
iso_alternatives
=
[]
for
e
in
base_entry
.
all_alternatives
():
iso_entry
=
self
.
adapt_method_entry
(
e
)
iso_alternatives
.
append
(
iso_entry
)
iso_entry
.
overloaded_alternatives
=
iso_alternatives
return
iso_alternatives
[
0
]
else
:
base_entry_type
=
base_entry
.
type
adapted_type
=
self
.
adapt
(
base_entry_type
)
if
adapted_type
is
base_entry_type
:
return
base_entry
else
:
entry
=
copy
.
copy
(
base_entry
)
entry
.
type
=
adapted_type
return
entry
class
TemplateScope
(
Scope
):
class
TemplateScope
(
Scope
):
def
__init__
(
self
,
name
,
outer_scope
):
def
__init__
(
self
,
name
,
outer_scope
):
Scope
.
__init__
(
self
,
name
,
outer_scope
,
None
)
Scope
.
__init__
(
self
,
name
,
outer_scope
,
None
)
...
...
Cython/Compiler/TypeInference.py
View file @
11915abb
...
@@ -538,6 +538,8 @@ def simply_type(result_type, pos):
...
@@ -538,6 +538,8 @@ def simply_type(result_type, pos):
result_type
=
result_type
.
ref_base_type
result_type
=
result_type
.
ref_base_type
if
result_type
.
is_cv_qualified
:
if
result_type
.
is_cv_qualified
:
result_type
=
result_type
.
cv_base_type
result_type
=
result_type
.
cv_base_type
if
result_type
.
is_qualified_cyp_class
and
result_type
.
qualifier
==
'iso~'
:
result_type
=
PyrexTypes
.
cyp_class_qualified_type
(
result_type
.
qual_base_type
,
'iso'
)
if
result_type
.
is_cpp_class
:
if
result_type
.
is_cpp_class
:
result_type
.
check_nullary_constructor
(
pos
)
result_type
.
check_nullary_constructor
(
pos
)
if
result_type
.
is_array
:
if
result_type
.
is_array
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment