Skip to content

Commit 8f16139

Browse files
committed
Revert "Sema: Remove some unreachable code from CSApply"
This reverts commit 9d3c8ca.
1 parent e1e0f54 commit 8f16139

File tree

7 files changed

+134
-26
lines changed

7 files changed

+134
-26
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ ERROR(cannot_apply_lvalue_binop_to_subelement,none,
225225
ERROR(cannot_apply_lvalue_binop_to_rvalue,none,
226226
"left side of mutating operator has immutable type %0", (Type))
227227

228+
ERROR(cannot_subscript_base,none,
229+
"cannot subscript a value of type %0",
230+
(Type))
231+
232+
ERROR(cannot_subscript_ambiguous_base,none,
233+
"cannot subscript a value of incorrect or ambiguous type", ())
234+
228235
ERROR(cannot_subscript_nil_literal,none,
229236
"cannot subscript a nil literal value", ())
230237
ERROR(conditional_cast_from_nil,none,

include/swift/AST/Expr.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,9 +3148,24 @@ class LoadExpr : public ImplicitConversionExpr {
31483148
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Load; }
31493149
};
31503150

3151+
/// This is a conversion from an expression of UnresolvedType to an arbitrary
3152+
/// other type, and from an arbitrary type to UnresolvedType. This node does
3153+
/// not appear in valid code, only in code involving diagnostics.
3154+
class UnresolvedTypeConversionExpr : public ImplicitConversionExpr {
3155+
public:
3156+
UnresolvedTypeConversionExpr(Expr *subExpr, Type type)
3157+
: ImplicitConversionExpr(ExprKind::UnresolvedTypeConversion, subExpr, type) {}
3158+
3159+
static bool classof(const Expr *E) {
3160+
return E->getKind() == ExprKind::UnresolvedTypeConversion;
3161+
}
3162+
};
3163+
31513164
/// FunctionConversionExpr - Convert a function to another function type,
31523165
/// which might involve renaming the parameters or handling substitutions
31533166
/// of subtypes (in the return) or supertypes (in the input).
3167+
///
3168+
/// FIXME: This should be a CapturingExpr.
31543169
class FunctionConversionExpr : public ImplicitConversionExpr {
31553170
public:
31563171
FunctionConversionExpr(Expr *subExpr, Type type)

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ ABSTRACT_EXPR(Apply, Expr)
151151
ABSTRACT_EXPR(ImplicitConversion, Expr)
152152
EXPR(Load, ImplicitConversionExpr)
153153
EXPR(DestructureTuple, ImplicitConversionExpr)
154+
EXPR(UnresolvedTypeConversion, ImplicitConversionExpr)
154155
EXPR(FunctionConversion, ImplicitConversionExpr)
155156
EXPR(CovariantFunctionConversion, ImplicitConversionExpr)
156157
EXPR(CovariantReturnConversion, ImplicitConversionExpr)

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2270,6 +2270,11 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
22702270
printRec(E->getResultExpr());
22712271
PrintWithColorRAII(OS, ParenthesisColor) << ')';
22722272
}
2273+
void visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E) {
2274+
printCommon(E, "unresolvedtype_conversion_expr") << '\n';
2275+
printRec(E->getSubExpr());
2276+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2277+
}
22732278
void visitFunctionConversionExpr(FunctionConversionExpr *E) {
22742279
printCommon(E, "function_conversion_expr") << '\n';
22752280
printRec(E->getSubExpr());

lib/AST/Expr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
338338

339339
PASS_THROUGH_REFERENCE(Load, getSubExpr);
340340
NO_REFERENCE(DestructureTuple);
341+
NO_REFERENCE(UnresolvedTypeConversion);
341342
PASS_THROUGH_REFERENCE(FunctionConversion, getSubExpr);
342343
PASS_THROUGH_REFERENCE(CovariantFunctionConversion, getSubExpr);
343344
PASS_THROUGH_REFERENCE(CovariantReturnConversion, getSubExpr);
@@ -662,6 +663,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
662663

663664
case ExprKind::Load:
664665
case ExprKind::DestructureTuple:
666+
case ExprKind::UnresolvedTypeConversion:
665667
case ExprKind::FunctionConversion:
666668
case ExprKind::CovariantFunctionConversion:
667669
case ExprKind::CovariantReturnConversion:

lib/SILGen/SILGenExpr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ namespace {
446446
RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E,
447447
SGFContext C);
448448
RValue visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E, SGFContext C);
449+
RValue visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
450+
SGFContext C);
449451
RValue visitFunctionConversionExpr(FunctionConversionExpr *E,
450452
SGFContext C);
451453
RValue visitCovariantFunctionConversionExpr(
@@ -956,6 +958,12 @@ RValue RValueEmitter::visitSuperRefExpr(SuperRefExpr *E, SGFContext C) {
956958
return RValue(SGF, E, result);
957959
}
958960

961+
RValue RValueEmitter::
962+
visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
963+
SGFContext C) {
964+
llvm_unreachable("invalid code made its way into SILGen");
965+
}
966+
959967
RValue RValueEmitter::visitOtherConstructorDeclRefExpr(
960968
OtherConstructorDeclRefExpr *E, SGFContext C) {
961969
// This should always be a child of an ApplyExpr and so will be emitted by

lib/Sema/CSApply.cpp

Lines changed: 96 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2884,7 +2884,8 @@ namespace {
28842884
auto type = simplifyType(openedType);
28852885
cs.setType(expr, type);
28862886

2887-
assert(!type->is<UnresolvedType>());
2887+
if (type->is<UnresolvedType>())
2888+
return expr;
28882889

28892890
auto &ctx = cs.getASTContext();
28902891

@@ -2907,11 +2908,14 @@ namespace {
29072908
ConcreteDeclRef witness = conformance.getWitnessByName(
29082909
conformingType->getRValueType(), constrName);
29092910

2910-
auto selectedOverload = solution.getOverloadChoice(
2911+
auto selectedOverload = solution.getOverloadChoiceIfAvailable(
29112912
cs.getConstraintLocator(expr, ConstraintLocator::ConstructorMember));
29122913

2914+
if (!selectedOverload)
2915+
return nullptr;
2916+
29132917
auto fnType =
2914-
simplifyType(selectedOverload.openedType)->castTo<FunctionType>();
2918+
simplifyType(selectedOverload->openedType)->castTo<FunctionType>();
29152919

29162920
auto newArg = coerceCallArguments(
29172921
expr->getArg(), fnType, witness,
@@ -3211,8 +3215,18 @@ namespace {
32113215
// Determine the declaration selected for this overloaded reference.
32123216
auto memberLocator = cs.getConstraintLocator(expr,
32133217
ConstraintLocator::Member);
3214-
auto selected = solution.getOverloadChoice(memberLocator);
3218+
auto selectedElt = solution.getOverloadChoiceIfAvailable(memberLocator);
3219+
3220+
if (!selectedElt) {
3221+
// If constraint solving resolved this to an UnresolvedType, then we're
3222+
// in an ambiguity tolerant mode used for diagnostic generation. Just
3223+
// leave this as whatever type of member reference it already is.
3224+
Type resultTy = simplifyType(cs.getType(expr));
3225+
cs.setType(expr, resultTy);
3226+
return expr;
3227+
}
32153228

3229+
auto selected = *selectedElt;
32163230
if (!selected.choice.getBaseType()) {
32173231
// This is one of the "outer alternatives", meaning the innermost
32183232
// methods didn't work out.
@@ -3444,19 +3458,40 @@ namespace {
34443458
Expr *visitSubscriptExpr(SubscriptExpr *expr) {
34453459
auto *memberLocator =
34463460
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
3447-
auto overload = solution.getOverloadChoice(memberLocator);
3461+
auto overload = solution.getOverloadChoiceIfAvailable(memberLocator);
3462+
3463+
// Handles situation where there was a solution available but it didn't
3464+
// have a proper overload selected from subscript call, might be because
3465+
// solver was allowed to return free or unresolved types, which can
3466+
// happen while running diagnostics on one of the expressions.
3467+
if (!overload) {
3468+
auto *base = expr->getBase();
3469+
auto &de = cs.getASTContext().Diags;
3470+
auto baseType = cs.getType(base);
34483471

3449-
if (overload.choice.getKind() ==
3472+
if (auto errorType = baseType->getAs<ErrorType>()) {
3473+
de.diagnose(base->getLoc(), diag::cannot_subscript_base,
3474+
errorType->getOriginalType())
3475+
.highlight(base->getSourceRange());
3476+
} else {
3477+
de.diagnose(base->getLoc(), diag::cannot_subscript_ambiguous_base)
3478+
.highlight(base->getSourceRange());
3479+
}
3480+
3481+
return nullptr;
3482+
}
3483+
3484+
if (overload->choice.getKind() ==
34503485
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
34513486
return buildDynamicMemberLookupRef(
34523487
expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(),
3453-
overload, memberLocator);
3488+
*overload, memberLocator);
34543489
}
34553490

34563491
return buildSubscript(
34573492
expr->getBase(), expr->getIndex(), expr->getArgumentLabels(),
34583493
expr->hasTrailingClosure(), cs.getConstraintLocator(expr),
3459-
expr->isImplicit(), expr->getAccessSemantics(), overload);
3494+
expr->isImplicit(), expr->getAccessSemantics(), *overload);
34603495
}
34613496

34623497
/// "Finish" an array expression by filling in the semantic expression.
@@ -4327,7 +4362,8 @@ namespace {
43274362
expr->getSubPattern()->forEachVariable([](VarDecl *VD) {
43284363
VD->setInvalid();
43294364
});
4330-
if (!SuppressDiagnostics) {
4365+
if (!SuppressDiagnostics
4366+
&& !cs.getType(simplified)->is<UnresolvedType>()) {
43314367
auto &de = cs.getASTContext().Diags;
43324368
de.diagnose(simplified->getLoc(), diag::pattern_in_expr,
43334369
expr->getSubPattern()->getKind());
@@ -4806,12 +4842,18 @@ namespace {
48064842
// If this is an unresolved link, make sure we resolved it.
48074843
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
48084844
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
4809-
auto foundDecl = solution.getOverloadChoice(locator);
4845+
auto foundDecl = solution.getOverloadChoiceIfAvailable(locator);
4846+
if (!foundDecl) {
4847+
// If we couldn't resolve the component, leave it alone.
4848+
resolvedComponents.push_back(origComponent);
4849+
componentTy = origComponent.getComponentType();
4850+
continue;
4851+
}
48104852

48114853
isDynamicMember =
4812-
foundDecl.choice.getKind() ==
4854+
foundDecl->choice.getKind() ==
48134855
OverloadChoiceKind::DynamicMemberLookup ||
4814-
foundDecl.choice.getKind() ==
4856+
foundDecl->choice.getKind() ==
48154857
OverloadChoiceKind::KeyPathDynamicMemberLookup;
48164858

48174859
// If this was a @dynamicMemberLookup property, then we actually
@@ -4842,9 +4884,11 @@ namespace {
48424884
case KeyPathExpr::Component::Kind::OptionalChain: {
48434885
didOptionalChain = true;
48444886
// Chaining always forces the element to be an rvalue.
4845-
assert(!componentTy->hasUnresolvedType());
48464887
auto objectTy =
48474888
componentTy->getWithoutSpecifierType()->getOptionalObjectType();
4889+
if (componentTy->hasUnresolvedType() && !objectTy) {
4890+
objectTy = componentTy;
4891+
}
48484892
assert(objectTy);
48494893

48504894
auto loc = origComponent.getLoc();
@@ -4896,8 +4940,8 @@ namespace {
48964940
}
48974941

48984942
// Wrap a non-optional result if there was chaining involved.
4899-
assert(!componentTy->hasUnresolvedType());
49004943
if (didOptionalChain && componentTy &&
4944+
!componentTy->hasUnresolvedType() &&
49014945
!componentTy->getWithoutSpecifierType()->isEqual(leafTy)) {
49024946
assert(leafTy->getOptionalObjectType()->isEqual(
49034947
componentTy->getWithoutSpecifierType()));
@@ -4916,8 +4960,8 @@ namespace {
49164960

49174961
// The final component type ought to line up with the leaf type of the
49184962
// key path.
4919-
assert(!componentTy->hasUnresolvedType());
4920-
assert(componentTy->getWithoutSpecifierType()->isEqual(leafTy));
4963+
assert(!componentTy || componentTy->hasUnresolvedType()
4964+
|| componentTy->getWithoutSpecifierType()->isEqual(leafTy));
49214965

49224966
if (!isFunctionType)
49234967
return E;
@@ -5022,13 +5066,18 @@ namespace {
50225066

50235067
// Unwrap the last component type, preserving @lvalue-ness.
50245068
auto optionalTy = components.back().getComponentType();
5025-
assert(!optionalTy->hasUnresolvedType());
50265069
Type objectTy;
50275070
if (auto lvalue = optionalTy->getAs<LValueType>()) {
50285071
objectTy = lvalue->getObjectType()->getOptionalObjectType();
5072+
if (optionalTy->hasUnresolvedType() && !objectTy) {
5073+
objectTy = optionalTy;
5074+
}
50295075
objectTy = LValueType::get(objectTy);
50305076
} else {
50315077
objectTy = optionalTy->getOptionalObjectType();
5078+
if (optionalTy->hasUnresolvedType() && !objectTy) {
5079+
objectTy = optionalTy;
5080+
}
50325081
}
50335082
assert(objectTy);
50345083

@@ -5457,9 +5506,11 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType) {
54575506
Type toInstanceType = toType;
54585507

54595508
// Look through metatypes
5460-
while (fromInstanceType->is<AnyMetatypeType>() &&
5509+
while ((fromInstanceType->is<UnresolvedType>() ||
5510+
fromInstanceType->is<AnyMetatypeType>()) &&
54615511
toInstanceType->is<ExistentialMetatypeType>()) {
5462-
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
5512+
if (!fromInstanceType->is<UnresolvedType>())
5513+
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
54635514
toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getInstanceType();
54645515
}
54655516

@@ -5659,6 +5710,11 @@ Expr *ExprRewriter::coerceCallArguments(
56595710
LocatorPathElt::ApplyArgToParam(argIdx, paramIdx, flags));
56605711
};
56615712

5713+
bool matchCanFail =
5714+
llvm::any_of(params, [](const AnyFunctionType::Param &param) {
5715+
return param.getPlainType()->hasUnresolvedType();
5716+
});
5717+
56625718
// Determine whether this application has curried self.
56635719
bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : true;
56645720
// Determine the parameter bindings.
@@ -5716,7 +5772,9 @@ Expr *ExprRewriter::coerceCallArguments(
57165772
args, params, paramInfo, unlabeledTrailingClosureIndex,
57175773
/*allowFixes=*/false, listener, trailingClosureMatching);
57185774

5719-
assert(callArgumentMatch && "Call arguments did not match up?");
5775+
assert((matchCanFail || callArgumentMatch) &&
5776+
"Call arguments did not match up?");
5777+
(void)matchCanFail;
57205778

57215779
auto parameterBindings = std::move(callArgumentMatch->parameterBindings);
57225780

@@ -6453,7 +6511,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
64536511
if (knownRestriction != solution.ConstraintRestrictions.end()) {
64546512
switch (knownRestriction->second) {
64556513
case ConversionRestrictionKind::DeepEquality: {
6456-
assert(!toType->hasUnresolvedType());
6514+
if (toType->hasUnresolvedType())
6515+
break;
64576516

64586517
// HACK: Fix problem related to Swift 4 mode (with assertions),
64596518
// since Swift 4 mode allows passing arguments with extra parens
@@ -6999,8 +7058,9 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
69997058
break;
70007059
}
70017060

7002-
assert(!fromType->hasUnresolvedType());
7003-
assert(!toType->hasUnresolvedType());
7061+
// Unresolved types come up in diagnostics for lvalue and inout types.
7062+
if (fromType->hasUnresolvedType() || toType->hasUnresolvedType())
7063+
return cs.cacheType(new (ctx) UnresolvedTypeConversionExpr(expr, toType));
70047064

70057065
// Use an opaque type to abstract a value of the underlying concrete type.
70067066
if (toType->getAs<OpaqueTypeArchetypeType>()) {
@@ -7577,14 +7637,19 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
75777637
// FIXME: handle unwrapping everywhere else
75787638
assert(!unwrapResult);
75797639

7580-
assert(!cs.getType(fn)->is<UnresolvedType>());
7640+
// If this is an UnresolvedType in the system, preserve it.
7641+
if (cs.getType(fn)->is<UnresolvedType>()) {
7642+
cs.setType(apply, cs.getType(fn));
7643+
return apply;
7644+
}
75817645

75827646
// We have a type constructor.
75837647
auto metaTy = cs.getType(fn)->castTo<AnyMetatypeType>();
75847648
auto ty = metaTy->getInstanceType();
75857649

75867650
// If we're "constructing" a tuple type, it's simply a conversion.
75877651
if (auto tupleTy = ty->getAs<TupleType>()) {
7652+
// FIXME: Need an AST to represent this properly.
75887653
return coerceToType(apply->getArg(), tupleTy, locator);
75897654
}
75907655

@@ -7593,14 +7658,19 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
75937658
auto *ctorLocator =
75947659
cs.getConstraintLocator(locator, {ConstraintLocator::ApplyFunction,
75957660
ConstraintLocator::ConstructorMember});
7596-
auto selected = solution.getOverloadChoice(ctorLocator);
7661+
auto selected = solution.getOverloadChoiceIfAvailable(ctorLocator);
7662+
if (!selected) {
7663+
assert(ty->hasError() || ty->hasUnresolvedType());
7664+
cs.setType(apply, ty);
7665+
return apply;
7666+
}
75977667

75987668
assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
75997669
ty->isExistentialType() || ty->is<ArchetypeType>());
76007670

76017671
// Consider the constructor decl reference expr 'implicit', but the
76027672
// constructor call expr itself has the apply's 'implicitness'.
7603-
Expr *declRef = buildMemberRef(fn, /*dotLoc=*/SourceLoc(), selected,
7673+
Expr *declRef = buildMemberRef(fn, /*dotLoc=*/SourceLoc(), *selected,
76047674
DeclNameLoc(fn->getEndLoc()), locator,
76057675
ctorLocator, /*implicit=*/true,
76067676
AccessSemantics::Ordinary);

0 commit comments

Comments
 (0)