Skip to content

Self.NestedType() doesn't create ConstructorRefCallExpr #65678

@keith

Description

@keith

With this code:

struct Bar {
  struct Nested<T> {
    init(value: T) {}
  }

  static func baz() -> Bar.Nested<Int> {
    Self.Nested(value: 0)
  }
}

The AST doesn't have a constructor_ref_call_expr, which leads to issues with missing index data attempting to index the implicit constructor that should be here.

Here's the produced AST:

(source_file "selfclass.swift"
  (struct_decl range=[selfclass.swift:1:1 - line:9:1] "Bar" interface type='Bar.Type' access=internal non-resilient
    (struct_decl range=[selfclass.swift:2:3 - line:4:3] "Nested" <T> interface type='Bar.Nested<T>.Type' access=internal non-resilient
      (constructor_decl range=[selfclass.swift:3:5 - line:3:21] "init(value:)" interface type='<T> (Bar.Nested<T>.Type) -> (T) -> Bar.Nested<T>' access=internal captures=(<generic> ) designated
        (parameter "self")
        (parameter_list range=[selfclass.swift:3:9 - line:3:18]
          (parameter "value" apiName=value type='T' interface type='T'))
        (brace_stmt range=[selfclass.swift:3:20 - line:3:21]
          (return_stmt implicit range=[selfclass.swift:3:21 - line:3:21]))))
    (func_decl range=[selfclass.swift:6:3 - line:8:3] "baz()" interface type='(Bar.Type) -> () -> Bar.Nested<Int>' access=internal type
      (parameter "self")
      (parameter_list range=[selfclass.swift:6:18 - line:6:19])
      (result
        (type_ident
          (component id='Bar' bind=selfclass.(file).Bar@selfclass.swift:1:8)
          (component id='Nested' bind=selfclass.(file).Bar.Nested@selfclass.swift:2:10)
            (type_ident
              (component id='Int' bind=Swift.(file).Int))))
      (call_expr type='Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:25] nothrow
        (autoclosure_expr type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] discriminator=0 escaping

          (parameter_list
            (parameter "value" apiName=value type='Int' interface type='Int'))
          (call_expr implicit type='Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] nothrow
            (dot_syntax_call_expr implicit type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] nothrow
              (declref_expr implicit type='(Bar.Nested<Int>.Type) -> (Int) -> Bar.Nested<Int>' location=selfclass.swift:7:10 range=[selfclass.swift:7:10 - line:7:10] decl=selfclass.(file).Bar.Nested.init(value:)@selfclass.swift:3:5 [with (substitution_map generic_signature=<T> (substitution T -> Int))] function_ref=single)
              (argument_list implicit
                (argument
                  (dot_self_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10]
                    (dot_syntax_base_ignored type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10]
                      (type_expr type='Bar.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:5] typerepr='Bar')
                      (type_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:10 range=[selfclass.swift:7:10 - line:7:10] typerepr='Nested'))))))
            (argument_list implicit labels=value:
              (argument label=value
                (declref_expr implicit type='Int' decl=selfclass.(file).Bar.baz().autoclosure discriminator=0.value function_ref=unapplied)))))
        (argument_list labels=value:
          (argument label=value
            (integer_literal_expr type='Int' location=selfclass.swift:7:24 range=[selfclass.swift:7:24 - line:7:24] value=0 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**)))))
    (constructor_decl implicit range=[selfclass.swift:1:8 - line:1:8] "init()" interface type='(Bar.Type) -> () -> Bar' access=internal designated
      (parameter "self")
      (parameter_list)
      (brace_stmt implicit range=[selfclass.swift:1:8 - line:1:8]
        (return_stmt range=[selfclass.swift:1:8 - line:1:8])))))

And if I change Self to Bar, it works and this is the AST:

(source_file "selfclass.swift"
  (struct_decl range=[selfclass.swift:1:1 - line:9:1] "Bar" interface type='Bar.Type' access=internal non-resilient
    (struct_decl range=[selfclass.swift:2:3 - line:4:3] "Nested" <T> interface type='Bar.Nested<T>.Type' access=internal non-resilient
      (constructor_decl range=[selfclass.swift:3:5 - line:3:21] "init(value:)" interface type='<T> (Bar.Nested<T>.Type) -> (T) -> Bar.Nested<T>' access=internal captures=(<generic> ) designated
        (parameter "self")
        (parameter_list range=[selfclass.swift:3:9 - line:3:18]
          (parameter "value" apiName=value type='T' interface type='T'))
        (brace_stmt range=[selfclass.swift:3:20 - line:3:21]
          (return_stmt implicit range=[selfclass.swift:3:21 - line:3:21]))))
    (func_decl range=[selfclass.swift:6:3 - line:8:3] "baz()" interface type='(Bar.Type) -> () -> Bar.Nested<Int>' access=internal type
      (parameter "self")
      (parameter_list range=[selfclass.swift:6:18 - line:6:19])
      (result
        (type_ident
          (component id='Bar' bind=selfclass.(file).Bar@selfclass.swift:1:8)
          (component id='Nested' bind=selfclass.(file).Bar.Nested@selfclass.swift:2:10)
            (type_ident
              (component id='Int' bind=Swift.(file).Int))))
      (call_expr type='Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:5 - line:7:24] nothrow
        (constructor_ref_call_expr type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:5 - line:7:9] nothrow
          (declref_expr implicit type='(Bar.Nested<Int>.Type) -> (Int) -> Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:9 - line:7:9] decl=selfclass.(file).Bar.Nested.init(value:)@selfclass.swift:3:5 [with (substitution_map generic_signature=<T> (substitution T -> Int))] function_ref=single)
          (argument_list implicit
            (argument
              (type_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:9] typerepr='Bar.Nested'))))
        (argument_list labels=value:
          (argument label=value
            (integer_literal_expr type='Int' location=selfclass.swift:7:23 range=[selfclass.swift:7:23 - line:7:23] value=0 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**)))))
    (constructor_decl implicit range=[selfclass.swift:1:8 - line:1:8] "init()" interface type='(Bar.Type) -> () -> Bar' access=internal designated
      (parameter "self")
      (parameter_list)
      (brace_stmt implicit range=[selfclass.swift:1:8 - line:1:8]
        (return_stmt range=[selfclass.swift:1:8 - line:1:8])))))

The diff is significant:

--- expected.txt	2023-05-04 16:27:39.720262764 -0700
+++ actual.txt	2023-05-04 16:27:35.334559338 -0700
@@ -16,15 +16,26 @@
           (component id='Nested' bind=selfclass.(file).Bar.Nested@selfclass.swift:2:10)
             (type_ident
               (component id='Int' bind=Swift.(file).Int))))
-      (call_expr type='Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:5 - line:7:24] nothrow
-        (constructor_ref_call_expr type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:5 - line:7:9] nothrow
-          (declref_expr implicit type='(Bar.Nested<Int>.Type) -> (Int) -> Bar.Nested<Int>' location=selfclass.swift:7:9 range=[selfclass.swift:7:9 - line:7:9] decl=selfclass.(file).Bar.Nested.init(value:)@selfclass.swift:3:5 [with (substitution_map generic_signature=<T> (substitution T -> Int))] function_ref=single)
+      (call_expr type='Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:25] nothrow
+        (autoclosure_expr type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] discriminator=0 escaping
+
+          (parameter_list
+            (parameter "value" apiName=value type='Int' interface type='Int'))
+          (call_expr implicit type='Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] nothrow
+            (dot_syntax_call_expr implicit type='(Int) -> Bar.Nested<Int>' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10] nothrow
+              (declref_expr implicit type='(Bar.Nested<Int>.Type) -> (Int) -> Bar.Nested<Int>' location=selfclass.swift:7:10 range=[selfclass.swift:7:10 - line:7:10] decl=selfclass.(file).Bar.Nested.init(value:)@selfclass.swift:3:5 [with (substitution_map generic_signature=<T> (substitution T -> Int))] function_ref=single)
           (argument_list implicit
             (argument
-              (type_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:9] typerepr='Bar.Nested'))))
+                  (dot_self_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10]
+                    (dot_syntax_base_ignored type='Bar.Nested<Int>.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:10]
+                      (type_expr type='Bar.Type' location=selfclass.swift:7:5 range=[selfclass.swift:7:5 - line:7:5] typerepr='Bar')
+                      (type_expr type='Bar.Nested<Int>.Type' location=selfclass.swift:7:10 range=[selfclass.swift:7:10 - line:7:10] typerepr='Nested'))))))
+            (argument_list implicit labels=value:
+              (argument label=value
+                (declref_expr implicit type='Int' decl=selfclass.(file).Bar.baz().autoclosure discriminator=0.value function_ref=unapplied)))))
         (argument_list labels=value:
           (argument label=value
-            (integer_literal_expr type='Int' location=selfclass.swift:7:23 range=[selfclass.swift:7:23 - line:7:23] value=0 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**)))))
+            (integer_literal_expr type='Int' location=selfclass.swift:7:24 range=[selfclass.swift:7:24 - line:7:24] value=0 builtin_initializer=Swift.(file).Int.init(_builtinIntegerLiteral:) initializer=**NULL**)))))
     (constructor_decl implicit range=[selfclass.swift:1:8 - line:1:8] "init()" interface type='(Bar.Type) -> () -> Bar' access=internal designated
       (parameter "self")
       (parameter_list)

3087afc

Metadata

Metadata

Assignees

No one assigned

    Labels

    Self in struct & enumFeature → types: The 'Self' type in structures and enumerationsbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.call expressionsFeature → expressions: Call expressionsexpressionsFeature: expressionsindexingArea → source tooling: AST indexinginitFeature → declarations: Initializersnested typesFeature: nested typessource toolingArea: IDE support, SourceKit, and other source toolingswift 5.8typesFeature: typesunexpected behaviorBug: Unexpected behavior or incorrect output

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions