From e5d26627db997cca2ababc052561d021f375fba1 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Wed, 31 Aug 2022 12:12:16 -0700 Subject: [PATCH 1/2] [CSSimplify] Replace `locatorEndsWith` with `isLastElement` accessor --- lib/Sema/CSSimplify.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 77fdbaeb6f4b4..1f1c28fcad64b 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -8865,13 +8865,6 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs, return cs.simplifyType(cs.getType(expr))->getRValueType(); }; - auto locatorEndsWith = - [](ConstraintLocator *locator, - ConstraintLocator::PathElementKind eltKind) -> bool { - auto path = locator->getPath(); - return !path.empty() && path.back().getKind() == eltKind; - }; - Expr *baseExpr = nullptr; Type baseType; @@ -8928,7 +8921,7 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs, // member. // We need to find type variable which represents contextual base. auto *baseLocator = cs.getConstraintLocator( - UME, locatorEndsWith(locator, ConstraintLocator::ConstructorMember) + UME, locator->isLastElement() ? ConstraintLocator::UnresolvedMember : ConstraintLocator::MemberRefBase); @@ -8943,7 +8936,7 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs, baseType = cs.simplifyType(*result)->getRValueType(); // Constraint for member base is formed as '$T.Type[.isLastElement()) baseType = MetatypeType::get(baseType); } else if (auto *keyPathExpr = getAsExpr(anchor)) { // Key path can't refer to initializers e.g. `\Type.init` From 4571c26f10afda9dd3789fba0fabb5a520e08f44 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Wed, 31 Aug 2022 12:21:14 -0700 Subject: [PATCH 2/2] [ConstraintSystem] Teach `init` ref validation about implicit conversions Implicit conversion used to erase path for contextual type conversions but it does so no longer, this means that invalid initializer reference check needs to know about existence of implicit conversions that are not reflected in the AST until solution is applied. Resolves: rdar://99352676 --- lib/Sema/CSSimplify.cpp | 4 ++++ .../implicit_double_cgfloat_conversion.swift | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 1f1c28fcad64b..41e8fbbe8841d 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -8861,6 +8861,10 @@ static ConstraintFix *validateInitializerRef(ConstraintSystem &cs, if (!anchor) return nullptr; + // Avoid checking implicit conversions injected by the compiler. + if (locator->findFirst()) + return nullptr; + auto getType = [&cs](Expr *expr) -> Type { return cs.simplifyType(cs.getType(expr))->getRValueType(); }; diff --git a/test/Constraints/implicit_double_cgfloat_conversion.swift b/test/Constraints/implicit_double_cgfloat_conversion.swift index e32394cbe1f90..653e136f4d4f9 100644 --- a/test/Constraints/implicit_double_cgfloat_conversion.swift +++ b/test/Constraints/implicit_double_cgfloat_conversion.swift @@ -330,3 +330,15 @@ func test_implicit_conversion_clash_with_partial_application_check() { } } } + +// rdar://99352676 +func test_init_validation() { + class Foo { + static let bar = 100.0 + + func getBar() -> CGFloat? { + return Self.bar + // CHECK: function_ref @$s12CoreGraphics7CGFloatVyACSdcfC : $@convention(method) (Double, @thin CGFloat.Type) -> CGFloat + } + } +}