diff --git a/mypyc/irbuild/specialize.py b/mypyc/irbuild/specialize.py index e810f11bd079..39bcbc708e3e 100644 --- a/mypyc/irbuild/specialize.py +++ b/mypyc/irbuild/specialize.py @@ -69,6 +69,7 @@ is_int64_rprimitive, is_int_rprimitive, is_list_rprimitive, + is_sequence_rprimitive, is_uint8_rprimitive, list_rprimitive, object_rprimitive, @@ -80,6 +81,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, @@ -221,17 +223,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 diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 612f3266fd79..e7074b13fe13 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -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#' + return 54