Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions mypyc/irbuild/specialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
is_int64_rprimitive,
is_int_rprimitive,
is_list_rprimitive,
is_sequence_rprimitive,
is_uint8_rprimitive,
list_rprimitive,
object_rprimitive,
Expand All @@ -81,6 +82,7 @@
from mypyc.irbuild.constant_fold import constant_fold_expr
from mypyc.irbuild.for_helpers import (
comprehension_helper,
get_expr_length_value,
sequence_from_generator_preallocate_helper,
translate_list_comprehension,
translate_set_comprehension,
Expand Down Expand Up @@ -222,17 +224,11 @@ def translate_len(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value
if len(expr.args) == 1 and expr.arg_kinds == [ARG_POS]:
arg = expr.args[0]
expr_rtype = builder.node_type(arg)
if isinstance(expr_rtype, RTuple):
# len() of fixed-length tuple can be trivially determined
# statically, though we still need to evaluate it.
builder.accept(arg)
return Integer(len(expr_rtype.types))
# NOTE (?) I'm not sure if my handling of can_borrow is correct here
obj = builder.accept(arg, can_borrow=is_list_rprimitive(expr_rtype))
if is_sequence_rprimitive(expr_rtype) or isinstance(expr_rtype, RTuple):
return get_expr_length_value(builder, arg, obj, expr.line, use_pyssize_t=False)
else:
if is_list_rprimitive(builder.node_type(arg)):
borrow = True
else:
borrow = False
obj = builder.accept(arg, can_borrow=borrow)
return builder.builtin_len(obj, expr.line)
return None

Expand Down
10 changes: 10 additions & 0 deletions mypyc/test-data/irbuild-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -3799,3 +3799,13 @@ L0:
r2.__mypyc_env__ = r0; r3 = is_error
wrapper = r2
return wrapper

[case testStaticLength]
def get_length() -> int:
return len("https://w3id.org/cwl/salad#")
[out]
def get_length():
r0 :: str
L0:
r0 = 'https://w3id.org/cwl/salad#'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to figure out how to avoid loading the constant at all, but I couldn't figure it out when I was implementing this PR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add an optimization pass at some point that removes unused pure values.

return 54