diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index c28f85d68ba38..e87cc9fd27fe1 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -1047,8 +1047,7 @@ namespace { // "T.init(...)" -- pretend it has two argument lists like // a real '.' call. if (isa(member) && - isa(prev) && - isa(cast(prev)->getFn())) { + isa(prev)) { assert(maxArgCount == 2); return 2; } diff --git a/lib/Sema/PreCheckTarget.cpp b/lib/Sema/PreCheckTarget.cpp index aa22b907a0221..afa9949cab369 100644 --- a/lib/Sema/PreCheckTarget.cpp +++ b/lib/Sema/PreCheckTarget.cpp @@ -1925,7 +1925,7 @@ TypeExpr *PreCheckTarget::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) { // CSGen will diagnose cases that appear outside of pack expansion // expressions. options |= TypeResolutionFlags::AllowPackReferences; - const auto BaseTy = TypeResolution::resolveContextualType( + auto BaseTy = TypeResolution::resolveContextualType( InnerTypeRepr, DC, options, [](auto unboundTy) { // FIXME: Don't let unbound generic types escape type resolution. @@ -1938,6 +1938,10 @@ TypeExpr *PreCheckTarget::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) { // TypeExpr pack elements are opened in CSGen. /*packElementOpener*/ nullptr); + // Unwrap DynamicSelfType, because Self.Foo is the same as MyClass.Foo. + if (auto *SelfTy = BaseTy->getAs()) + BaseTy = SelfTy->getSelfType(); + if (BaseTy->mayHaveMembers()) { // See if there is a member type with this name. auto Result = TypeChecker::lookupMemberType(DC, BaseTy, Name, diff --git a/test/Index/expressions.swift b/test/Index/expressions.swift index 9d92a191757f7..92dec3635b85b 100644 --- a/test/Index/expressions.swift +++ b/test/Index/expressions.swift @@ -57,3 +57,21 @@ func castExpr(x: Any) { // CHECK: [[@LINE+1]]:15 | struct/Swift | S1 | [[S1_USR]] | Ref _ = x as? S1 } + +// Test that initializers are indexed when called through Self.NestedType + +// CHECK: [[@LINE+1]]:7 | class(internal)/Swift | Container | [[Container_USR:.*]] | Def +class Container { + // CHECK: [[@LINE+1]]:11 | class(internal)/Swift | NestedType | [[NestedType_USR:.*]] | Def + class NestedType { + // CHECK: [[@LINE+1]]:9 | constructor(internal)/Swift | init(value:) | [[NestedType_init_USR:.*]] | Def + init(value: Int) {} + } + + func someFunc() { + // CHECK: [[@LINE+3]]:13 | class/Swift | Container | [[Container_USR]] | Ref + // CHECK: [[@LINE+2]]:18 | class/Swift | NestedType | [[NestedType_USR]] | Ref + // CHECK: [[@LINE+1]]:18 | constructor/Swift | init(value:) | [[NestedType_init_USR]] | Ref,Call + _ = Self.NestedType(value: 1) + } +} \ No newline at end of file diff --git a/test/SILGen/bogus_curry_thunk.swift b/test/SILGen/bogus_curry_thunk.swift new file mode 100644 index 0000000000000..3981808dbe1ec --- /dev/null +++ b/test/SILGen/bogus_curry_thunk.swift @@ -0,0 +1,58 @@ +// RUN: %target-swift-emit-silgen %s | %FileCheck %s + +class Container { + class NestedType {} + + func someFunc1() { + // This constructor call should not require a curry thunk. + _ = Container.NestedType() + } + + func someFunc2() { + // This constructor call should not require a curry thunk. + _ = Self.NestedType() + } + + func someFunc3() { + let m = Container.self + + // This constructor call should not require a curry thunk. + _ = m.NestedType() + } +} + +// CHECK-LABEL: sil hidden [ossa] @$s17bogus_curry_thunk9ContainerC9someFunc1yyF : $@convention(method) (@guaranteed Container) -> () { +// CHECK: bb0(%0 : @guaranteed $Container): +// CHECK: [[META2:%.*]] = metatype $@thick Container.NestedType.Type +// CHECK: [[FN:%.*]] = function_ref @$s17bogus_curry_thunk9ContainerC10NestedTypeCAEycfC : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: [[RESULT:%.*]] = apply [[FN]]([[META2]]) : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: ignored_use [[RESULT]] +// CHECK: destroy_value [[RESULT]] +// CHECK: [[TUPLE:%.*]] = tuple () +// CHECK: return [[TUPLE]] +// CHECK: } + + +// CHECK-LABEL: sil hidden [ossa] @$s17bogus_curry_thunk9ContainerC9someFunc2yyF : $@convention(method) (@guaranteed Container) -> () { +// CHECK: bb0(%0 : @guaranteed $Container): +// CHECK: [[META2:%.*]] = metatype $@thick Container.NestedType.Type +// CHECK: [[FN:%.*]] = function_ref @$s17bogus_curry_thunk9ContainerC10NestedTypeCAEycfC : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: [[RESULT:%.*]] = apply [[FN]]([[META2]]) : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: ignored_use [[RESULT]] +// CHECK: destroy_value [[RESULT]] +// CHECK: [[TUPLE:%.*]] = tuple () +// CHECK: return [[TUPLE]] +// CHECK: } + + +// CHECK-LABEL: sil hidden [ossa] @$s17bogus_curry_thunk9ContainerC9someFunc3yyF : $@convention(method) (@guaranteed Container) -> () { +// CHECK: bb0(%0 : @guaranteed $Container): +// CHECK: [[META:%.*]] = metatype $@thick Container.Type +// CHECK: [[META2:%.*]] = metatype $@thick Container.NestedType.Type +// CHECK: [[FN:%.*]] = function_ref @$s17bogus_curry_thunk9ContainerC10NestedTypeCAEycfC : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: [[RESULT:%.*]] = apply [[FN]]([[META2]]) : $@convention(method) (@thick Container.NestedType.Type) -> @owned Container.NestedType +// CHECK: ignored_use [[RESULT]] +// CHECK: destroy_value [[RESULT]] +// CHECK: [[TUPLE:%.*]] = tuple () +// CHECK: return [[TUPLE]] +// CHECK: } diff --git a/test/type/self.swift b/test/type/self.swift index 1bdf610e96f5c..361d601dbf964 100644 --- a/test/type/self.swift +++ b/test/type/self.swift @@ -380,4 +380,17 @@ struct NonGeneric { protocol P { func foo() -> Self // expected-error@-1 {{cannot specialize non-generic type 'Self'}} +} + +// https://github.com/peripheryapp/periphery/issues/676 + +class Container { + class NestedType { + init(value: Int) {} + } + + func someFunc() { + let _ = [Container.NestedType]() // ok + let _ = [Self.NestedType]() // ok + } } \ No newline at end of file